package com.xiaoshuidi.cloud.module.rooms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.*;
import cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoshuidi.cloud.framework.common.exception.ErrorCode;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.framework.filings.config.FilingsProperties;
import com.xiaoshuidi.cloud.framework.filings.core.enums.*;
import com.xiaoshuidi.cloud.framework.filings.core.service.dto.InventoryCheckBo;
import com.xiaoshuidi.cloud.framework.filings.core.service.dto.InventoryRoomCheckBo;
import com.xiaoshuidi.cloud.framework.oss.core.OosFileService;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.apartment.vo.ApartmentVO;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomel.vo.RoomelCreateReqVO;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomel.vo.RoomelUpdateReqVO;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomequipment.vo.RoomEquipmentQueryResp;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomhouse.vo.*;
import com.xiaoshuidi.cloud.module.rooms.convert.apartment.ApartmentConvert;
import com.xiaoshuidi.cloud.module.rooms.convert.roomhouse.RoomHouseConvert;
import com.xiaoshuidi.cloud.module.rooms.convert.roomhouseinfo.RoomHouseInfoConvert;
import com.xiaoshuidi.cloud.module.rooms.enums.*;
import com.xiaoshuidi.cloud.module.rooms.framework.utils.BaiDuMapUtil;
import com.xiaoshuidi.cloud.module.rooms.framework.utils.CodeUtil;
import com.xiaoshuidi.cloud.module.rooms.framework.utils.GaoDeUtil;
import com.xiaoshuidi.cloud.module.rooms.framework.utils.RoomHouseUtil;
import com.xiaoshuidi.cloud.module.rooms.mapper.RoomHouseMapper;
import com.xiaoshuidi.cloud.module.rooms.mq.event.InventoryCheckEvent;
import com.xiaoshuidi.cloud.module.rooms.mq.listener.PartListener;
import com.xiaoshuidi.cloud.module.rooms.mq.listener.WholeLeaseListener;
import com.xiaoshuidi.cloud.module.rooms.mq.producer.RoomEsProducer;
import com.xiaoshuidi.cloud.module.rooms.pojo.*;
import com.xiaoshuidi.cloud.module.rooms.pojo.roomel.RoomelEntity;
import com.xiaoshuidi.cloud.module.rooms.repository.*;
import com.xiaoshuidi.cloud.module.rooms.repository.elsticsearch.RoomelEntityRepository;
import com.xiaoshuidi.cloud.module.rooms.service.RoomHouseService;
import com.xiaoshuidi.cloud.module.rooms.service.RoomHouseTypeService;
import com.xiaoshuidi.cloud.module.rooms.service.RoomStateRecordService;
import com.xiaoshuidi.cloud.module.rooms.vo.RoomHouseRespVo;
import com.xiaoshuidi.cloud.module.system.api.user.AdminUserApi;
import com.xiaoshuidi.cloud.module.system.api.user.dto.AdminUserRespDTO;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedTopHits;
import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Marker;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.zxp.esclientrhl.repository.ElasticsearchTemplate;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.xiaoshuidi.cloud.module.rooms.enums.ErrorCodeConstants.*;
import static com.xiaoshuidi.cloud.module.rooms.pojo.roomel.RoomelEntityMapping.*;

import static com.xiaoshuidi.cloud.module.rooms.enums.ErrorCodeConstants.ADDRESS_ERROR;


@Slf4j
@Service
@RequiredArgsConstructor
public class RoomHouseServiceImpl extends ServiceImpl<RoomHouseMapper, RoomHouse> implements RoomHouseService {
    // 最大分组数量
    private static final Integer MAX_GROUP_SIZE = 10000;

    private final RoomFloorRepository roomFloorRepository;
    private final ApartmentRepository apartmentRepository;
    private final RoomHouseRepository roomHouseRepository;
    private final RoomLayoutRepository roomLayoutRepository;
    private final RoomAreaRepository roomAreaRepository;
    private final GaoDeUtil gaoDeUtil;
    private final CodeUtil codeUtil;
    private final RoomApartmentAreaRepository roomApartmentAreaRepository;
    private final RoomHouseInfoRepository roomHouseInfoRepository;
    private final RoomHouseTypeRepository roomHouseTypeRepository;
    private final ApplicationEventPublisher publisher;
    private final FilingsProperties filingsProperties;
    private final RoomHouseFilingsRepository roomHouseFilingsRepository;
    private final RoomStateRecordRepository roomStateRecordRepository;
    private final RoomStateRecordService roomStateRecordService;
    private final RoomEsProducer roomEsProducer;
    private final PlatformTransactionManager transactionManager;
    private final TransactionDefinition transactionDefinition;
    private final OosFileService oosFileService;
    private final StringRedisTemplate redisTemplate;
    private final ElasticsearchTemplate elasticsearchTemplate;
    private final RoomHouseTypeService houseTypeService;
    private final AdminUserApi adminUserApi;
    private final RoomelEntityRepository roomelEntityRepository;
    private final BaiDuMapUtil baiDuMapUtil;
    private final RoomEquipmentRepository roomEquipmentRepository;

    private final RoomHouseEstimateRepository roomHouseEstimateRepository;

    @Override
    public CommonResult<Boolean> insertBatch(List<RoomHouse> roomHouses) {
        Assert.isTrue(ArrayUtil.isNotEmpty(roomHouses), "房间列表不能为空!");
        roomHouseRepository.saveBatch(roomHouses);
        return CommonResult.success(true);
    }

    @Override
    public RoomHouse insert(RoomHouse roomHouse) {
        roomHouseRepository.save(roomHouse);
        return roomHouse;
    }

    /**
     * 分散式房间新增
     *
     * @param roomHouseId
     * @param loginUserId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<RoomCreateRespVo> addRoomHouse(@NonNull Long roomHouseId, Long loginUserId) {
        // 修改楼层房间数量
        RoomHouse roomHouse = roomHouseRepository.getById(roomHouseId);
        Assert.isTrue(ObjectUtil.isNotEmpty(roomHouse), "房源不存在");
        RoomFloor roomFloor = roomFloorRepository.getById(roomHouse.getFloorId());
        roomFloor.setFloorRoomNum(roomFloor.getFloorRoomNum() + 1);
        roomFloorRepository.updateById(roomFloor);
        // 查询公寓信息
        Apartment apartment = apartmentRepository.getById(roomFloor.getApartmentId());
        Assert.isTrue(ObjectUtil.isNotEmpty(apartment), "公寓不存在");
        // 查询原来的房间信息
        List<RoomHouse> roomHouses = roomHouseRepository.getByFloorIdAndSuperId(roomFloor.getId(), roomHouseId);
        // 添加房间信息
        RoomHouse addRoomHouse = new RoomHouse();
        addRoomHouse.setName(String.format("%03d", roomHouses.size() + 1) + "间");
        addRoomHouse.setApartmentId(roomFloor.getApartmentId());
        addRoomHouse.setFloorId(roomFloor.getId());
        addRoomHouse.setRoomType(RoomTypeEnum.ZW.getName());
        addRoomHouse.setFloorNo(roomFloor.getNum().toString());
        addRoomHouse.setHouseNo(String.format("%02d", roomFloor.getNum()) + String.format("%03d", roomHouses.size() + 1) + "室");
        addRoomHouse.setIsWhole(false);
        addRoomHouse.setRoomNum(1);
        addRoomHouse.setLayoutId(null);
        addRoomHouse.setSuperId(roomHouseId);
        roomHouseRepository.save(addRoomHouse);
        return CommonResult.success(RoomCreateRespVo.builder().id(roomHouse.getId()).build());
    }

    /**
     * 添加集中式房源
     *
     * @param concentratedAddVO
     * @param tenantId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> concentratedAdd(ConcentratedAddVO concentratedAddVO, Long tenantId) {
        log.info("新增集中式房源,接收参数:{}", JSONObject.toJSONString(concentratedAddVO));
        // 校验公寓信息
        Apartment apartment = apartmentRepository.getById(concentratedAddVO.getApartmentId());
        Assert.isTrue(ObjectUtil.isNotEmpty(apartment), "公寓信息不存在");
        if (!ObjectUtil.isAllNotEmpty(apartment.getAddress(), apartment.getIsConcentrated())) {
            throw new ServiceException(new ErrorCode(20034, "请先维护门店信息"));
        }
        if (!apartment.getIsConcentrated()) {
            throw new ServiceException(new ErrorCode(20034, "分散式门店无法添加集中式房源"));
        }
        // 如果小区不存在,创建小区, 如果小区存在则查询小区的信息,存入apartment_area
        RoomArea roomArea = this.addRoomArea(
                concentratedAddVO.getAreaId(),
                concentratedAddVO.getAreaName(),
                concentratedAddVO.getProvince(),
                concentratedAddVO.getCity(),
                concentratedAddVO.getDistrict(),
                concentratedAddVO.getStreet(),
                concentratedAddVO.getAddress()
        );
        // 检查分散式是否存在该楼栋
        this.checkBuilding(concentratedAddVO.getProvince(),
                concentratedAddVO.getCity(),
                concentratedAddVO.getDistrict(),
                concentratedAddVO.getStreet(),
                concentratedAddVO.getAddress(),
                concentratedAddVO.getAreaName(),
                concentratedAddVO.getBuildingNo(),
                false);

        // 检验公寓小区是否已经存在
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.getOne(
                new LambdaQueryWrapper<RoomApartmentArea>()
                        .eq(ObjectUtil.isNotEmpty(concentratedAddVO.getProvince()), RoomApartmentArea::getProvince, concentratedAddVO.getProvince())
                        .eq(ObjectUtil.isNotEmpty(concentratedAddVO.getCity()), RoomApartmentArea::getCity, concentratedAddVO.getCity())
                        .eq(ObjectUtil.isNotEmpty(concentratedAddVO.getDistrict()), RoomApartmentArea::getDistrict, concentratedAddVO.getDistrict())
                        .eq(ObjectUtil.isNotEmpty(concentratedAddVO.getStreet()), RoomApartmentArea::getStreet, concentratedAddVO.getStreet())
                        .eq(ObjectUtil.isNotEmpty(concentratedAddVO.getAddress()), RoomApartmentArea::getAddress, concentratedAddVO.getAddress())
                        .eq(ObjectUtil.isNotEmpty(concentratedAddVO.getAreaName()), RoomApartmentArea::getArea, concentratedAddVO.getAreaName())
                        .eq(ObjectUtil.isNotEmpty(concentratedAddVO.getBuildingNo()), RoomApartmentArea::getBuildingNo, concentratedAddVO.getBuildingNo())
        );
        if (ObjectUtil.isNotEmpty(roomApartmentArea)) {
            // 检查楼栋是否已经在其他门店下
            if (!roomApartmentArea.getApartmentId().equals(concentratedAddVO.getApartmentId())) {
                throw new ServiceException(new ErrorCode(30034, "该楼栋已在其他门店下存在,请不要重复添加"));
            }
            // 检查楼层是否有重复
            List<RoomFloor> roomFloors = roomFloorRepository.getByApartmentAreaIdAndNum(roomApartmentArea.getId(), concentratedAddVO.getInFloorNum());
            if (ObjectUtil.isNotEmpty(roomFloors)) {
                throw new ServiceException(ErrorCodeConstants.HOUSE_FLOOR_REPEAT);
            }
        } else {
            // 保存公寓小区信息
            roomApartmentArea = this.saveApartmentArea(concentratedAddVO, roomArea, tenantId);
        }
        // 获取楼层和房间信息
        Map<Integer, List<RoomInfoDto>> roomInfo = concentratedAddVO.getRoomInfo();
        // 保存所有楼层和房间信息
        this.saveFloorAndRoomHouse(concentratedAddVO, roomApartmentArea, roomInfo, apartment, roomArea, tenantId);
        return CommonResult.success(Boolean.TRUE);
    }

    /**
     * 编辑时获取房源信息
     *
     * @param roomHouseId
     * @param tenantId
     * @return
     */
    @Override
    public CommonResult<RoomHouseInfoRespVO> getRoomHouseInfo(@NonNull Long roomHouseId, Long tenantId) {
        // 查询房间信息
        RoomHouse roomHouse = roomHouseRepository.getById(roomHouseId);
        Assert.isTrue(ObjectUtil.isNotEmpty(roomHouse), "房间信息不存在");

        // 查询公寓信息
        Apartment apartment = apartmentRepository.getById(roomHouse.getApartmentId());
        Assert.isTrue(ObjectUtil.isNotEmpty(apartment), "公寓信息不存在");

        StringBuilder apartmentAddress = new StringBuilder();
        apartmentAddress.append(apartment.getProvince());
        apartmentAddress.append(apartment.getCity());
        apartmentAddress.append(apartment.getDistrict());
        apartmentAddress.append(apartment.getStreet());
        apartmentAddress.append(apartment.getAddress());

        // 查询户型信息
        RoomHouseType roomHouseType = roomHouseTypeRepository.getById(roomHouse.getRoomHouseTypeId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomHouseType), "户型信息不存在");

        // 查询小区信息
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.getById(roomHouse.getApartmentAreaId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomApartmentArea), "小区信息不存在");

        RoomFloor roomFloor = roomFloorRepository.getById(roomHouse.getFloorId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomFloor), "楼层信息不存在");


        List<String> equipmentNames = new ArrayList<>();


        // 查询备案信息
        RoomHouseInfo roomHouseInfo = roomHouseInfoRepository.getByRoomHouseId(roomHouseId);
        RoomHouseInfoVO roomHouseInfoVO = RoomHouseInfoConvert.INSTANCE.convert(roomHouseInfo);

        // 如果是集中式,则查询房型信息
        RoomLayout roomLayout = new RoomLayout();
        if (roomHouse.getIsConcentrated()) {
            roomLayout = roomLayoutRepository.getById(roomHouse.getLayoutId());
            Assert.isTrue(ObjectUtil.isNotEmpty(roomLayout), "房型信息不存在");
        }

        MasterRoomInfo masterRoomInfo = new MasterRoomInfo();
        RoomHouseInfoRespVO respVO = new RoomHouseInfoRespVO();

        // 如果是合租
        List<RoomHouse> roomHouses = new ArrayList<>();
        if (!roomHouse.getIsWhole()) {
            //  查询子房间信息
            roomHouses = roomHouseRepository.getBySuperId(roomHouse.getSuperId()).getCheckedData();
            // 过滤掉停用的房间
            roomHouses = roomHouses.stream().filter(p -> !p.getIsStop()).collect(Collectors.toList());
            // 查询主房间信息
            RoomHouse masterRoomHouse = roomHouseRepository.getById(roomHouse.getSuperId());
            masterRoomInfo.setNo(masterRoomHouse.getNo());
            masterRoomInfo.setBuildingNo(roomApartmentArea.getBuildingNo());
            masterRoomInfo.setUnitNo(roomApartmentArea.getUnitNo());
            masterRoomInfo.setHouseNo(masterRoomHouse.getHouseNo());
            masterRoomInfo.setLayoutName(roomLayout.getName());
            masterRoomInfo.setLayoutId(roomLayout.getId());
            masterRoomInfo.setBedRoomNum(roomHouseType.getBedRoomNum());
            masterRoomInfo.setLivingRoomNum(roomHouseType.getLivingRoomNum());
            masterRoomInfo.setToiletNum(roomHouseType.getToiletNum());
            masterRoomInfo.setKitchenNum(roomHouseType.getKitchenNum());
            masterRoomInfo.setBalcony(roomHouseType.getBalcony());
            // 集中式取房型面积
            masterRoomInfo.setSpaceMin(roomLayout.getSpaceMin());
            masterRoomInfo.setSpaceMax(roomLayout.getSpaceMax());
            masterRoomInfo.setSpace(masterRoomHouse.getSpace());
            masterRoomInfo.setFloorNum(roomApartmentArea.getFloorNum());
            masterRoomInfo.setGroundFloorNum(roomApartmentArea.getGroundFloorNum());
            masterRoomInfo.setInFloorNum(masterRoomHouse.getFloorNo());
            masterRoomInfo.setToward(masterRoomHouse.getToward());
            masterRoomInfo.setPeopleNum(masterRoomHouse.getPeopleNum());
            masterRoomInfo.setFloorRoomNum(roomFloor.getFloorRoomNum());
            masterRoomInfo.setMonthRental(masterRoomHouse.getMonthRental());
            masterRoomInfo.setIsLock(masterRoomHouse.getIsLock());
            RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(masterRoomHouse.getId());
            masterRoomInfo.setHomeState(ObjectUtil.isEmpty(roomStateRecord) ? RentStatusEnum.EMPTY.getValue() : roomStateRecord.getState());
            RoomHouseFilings roomHouseFilings = roomHouseFilingsRepository.getByRoomHouseId(masterRoomHouse.getId());
            if (ObjectUtil.isNotEmpty(roomHouseFilings)) {
                masterRoomInfo.setCheckCode(roomHouseFilings.getCheckCode());
            }

            CommonResult<AdminUserRespDTO> result = adminUserApi.getUser(Long.valueOf(masterRoomHouse.getCreator()));
            if (result.isSuccess()) {
                AdminUserRespDTO adminUserRespDTO = result.getCheckedData();
                masterRoomInfo.setCreateUserName(adminUserRespDTO.getNickname());
            }

            String publicFacilities = masterRoomHouse.getPublicFacilities();
            if (ObjectUtil.isNotEmpty(publicFacilities)) {
                String[] split = publicFacilities.split(",");
                equipmentNames = Arrays.stream(split).collect(Collectors.toList());
            }

            respVO.setEquipments(equipmentNames);
            respVO.setPicUrl(masterRoomHouse.getPicUrl());
            respVO.setVideoUrl(masterRoomHouse.getVideoUrl());
            respVO.setVrUrl(masterRoomHouse.getVrUrl());
            respVO.setVrPicUrl(masterRoomHouse.getVrPicUrl());
        } else {
            // 整租
            masterRoomInfo.setNo(roomHouse.getNo());
            masterRoomInfo.setBuildingNo(roomApartmentArea.getBuildingNo());
            masterRoomInfo.setUnitNo(roomApartmentArea.getUnitNo());
            masterRoomInfo.setHouseNo(roomHouse.getHouseNo());
            masterRoomInfo.setLayoutName(roomLayout.getName());
            masterRoomInfo.setLayoutId(roomLayout.getId());
            masterRoomInfo.setBedRoomNum(roomHouseType.getBedRoomNum());
            masterRoomInfo.setLivingRoomNum(roomHouseType.getLivingRoomNum());
            masterRoomInfo.setToiletNum(roomHouseType.getToiletNum());
            masterRoomInfo.setKitchenNum(roomHouseType.getKitchenNum());
            masterRoomInfo.setBalcony(roomHouseType.getBalcony());
            // 集中式取房型面积
            masterRoomInfo.setSpaceMin(roomLayout.getSpaceMin());
            masterRoomInfo.setSpaceMax(roomLayout.getSpaceMax());
            masterRoomInfo.setSpace(roomHouse.getSpace());
            masterRoomInfo.setFloorNum(roomApartmentArea.getFloorNum());
            masterRoomInfo.setGroundFloorNum(roomApartmentArea.getGroundFloorNum());
            masterRoomInfo.setInFloorNum(roomHouse.getFloorNo());
            masterRoomInfo.setToward(roomHouse.getToward());
            masterRoomInfo.setPeopleNum(roomHouse.getPeopleNum());
            masterRoomInfo.setFloorRoomNum(roomFloor.getFloorRoomNum());
            masterRoomInfo.setMonthRental(roomHouse.getMonthRental());
            masterRoomInfo.setIsLock(roomHouse.getIsLock());

            RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouse.getId());
            masterRoomInfo.setHomeState(roomStateRecord.getState());
            RoomHouseFilings roomHouseFilings = roomHouseFilingsRepository.getByRoomHouseId(roomHouse.getId());
            if (ObjectUtil.isNotEmpty(roomHouseFilings)) {
                masterRoomInfo.setCheckCode(roomHouseFilings.getCheckCode());
                masterRoomInfo.setConcentratedCheckCode(roomHouseFilings.getCheckCode());
                masterRoomInfo.setConcentratedExternalHouseId(roomHouseFilings.getExternalHouseId());
            }

            respVO.setPicUrl(roomHouse.getPicUrl());
            respVO.setVideoUrl(roomHouse.getVideoUrl());
            respVO.setVrUrl(roomHouse.getVrUrl());
            respVO.setVrPicUrl(roomHouse.getVrPicUrl());
            if (!roomHouse.getIsConcentrated()) {
                // 分散式整租
                String publicFacilities = roomHouse.getPublicFacilities();
                if (ObjectUtil.isNotEmpty(publicFacilities)) {
                    String[] split = publicFacilities.split(",");
                    equipmentNames = Arrays.stream(split).collect(Collectors.toList());
                }
                respVO.setEquipments(equipmentNames);
            }
            if (StrUtil.isNotEmpty(roomHouse.getCreator())) {
                CommonResult<AdminUserRespDTO> result = adminUserApi.getUser(Long.valueOf(roomHouse.getCreator()));
                if (result.isSuccess()) {
                    AdminUserRespDTO adminUserRespDTO = result.getCheckedData();
                    masterRoomInfo.setCreateUserName(ObjectUtil.isNotEmpty(adminUserRespDTO) ? adminUserRespDTO.getNickname() : "");
                }
            }
        }

        List<SlaveRoomInfo> slaveRoomInfos = new ArrayList<>();

        for (RoomHouse room : roomHouses) {
            SlaveRoomInfo slaveRoomInfo = new SlaveRoomInfo();
            slaveRoomInfo.setRoomHouseId(room.getId());
            slaveRoomInfo.setRoomHouseNo(room.getHouseNo());
            slaveRoomInfo.setRoomType(room.getRoomType());
            slaveRoomInfo.setSpace(room.getSpace());
            slaveRoomInfo.setToward(room.getToward());
            slaveRoomInfo.setPeopleNum(room.getPeopleNum());
            slaveRoomInfos.add(slaveRoomInfo);
        }
        // 子房间排序
        slaveRoomInfos = slaveRoomInfos.stream().sorted(Comparator.comparing(SlaveRoomInfo::getRoomType)).collect(Collectors.toList());

        RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
        respVO.setHouseState(ObjectUtil.isEmpty(roomStateRecord) ? RentStatusEnum.EMPTY.getValue() : roomStateRecord.getState());
        respVO.setRoomHouseId(roomHouseId);
        respVO.setApartmentId(apartment.getId());
        respVO.setApartmentName(apartment.getName());
        respVO.setIsWhole(roomHouse.getIsWhole());
        respVO.setProvince(apartment.getProvince());
        respVO.setCity(apartment.getCity());
        respVO.setDistrict(roomHouse.getDistrict());
        respVO.setStreet(roomHouse.getStreet());
        respVO.setAddress(roomHouse.getAddress());
        respVO.setApartmentAddress(apartmentAddress.toString());
        respVO.setArea(roomHouse.getArea());
        respVO.setAreaId(roomApartmentArea.getRoomAreaId());
        respVO.setDecoration(roomHouse.getDecoration());
        respVO.setRoomHouseInfo(roomHouseInfoVO);
        respVO.setMasterRoomInfo(masterRoomInfo);
        respVO.setSlaveRoomInfo(slaveRoomInfos);
        respVO.setRoomUsage(roomHouse.getRoomUsage());
        respVO.setIsLock(roomHouse.getIsLock());
        respVO.setSpace(roomHouse.getSpace());
        respVO.setIsClean(roomHouse.getIsClean());
        respVO.setIsConcentrated(roomHouse.getIsConcentrated());
        return CommonResult.success(respVO);
    }


    /**
     * 编辑房源信息
     *
     * @param editReqVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> concentratedEdit(ConcentratedRoomHouseEditReqVO editReqVO) {
        RoomHouse roomHouse = roomHouseRepository.getById(editReqVO.getRoomHouseId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomHouse), "房间信息不存在");

        RoomLayout roomLayout = roomLayoutRepository.getById(editReqVO.getLayoutId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomLayout), "户型信息不存在");

        // 更新房间信息
        roomHouse.setLayoutId(editReqVO.getLayoutId());
        roomHouse.setToward(editReqVO.getToward());
        roomHouse.setDecoration(editReqVO.getDecoration());
        roomHouse.setRoomUsage(editReqVO.getRoomUsage());
        roomHouse.setSpace(editReqVO.getSpace());
        roomHouseRepository.updateById(roomHouse);

        // 更新备案信息
        RoomHouseInfo roomHouseInfo = roomHouseInfoRepository.getByRoomHouseId(editReqVO.getRoomHouseId());
        RecordInfoDto recordInfoDto = editReqVO.getRecordInfoDto();
        BeanUtil.copyProperties(recordInfoDto, roomHouseInfo);
        roomHouseInfoRepository.updateById(roomHouseInfo);

        if(ObjectUtil.isNotEmpty(recordInfoDto.getConcentratedExternalHouseId()) || ObjectUtil.isNotEmpty(recordInfoDto.getConcentratedCheckCode())){
            // 保存备案数据
            RoomHouseFilings roomHouseFilings = roomHouseFilingsRepository.getByRoomHouseId(roomHouse.getId());
            if (ObjectUtil.isNotEmpty(roomHouseFilings)) {
                roomHouseFilings.setExternalHouseId(recordInfoDto.getConcentratedExternalHouseId());
                roomHouseFilings.setCheckCode(recordInfoDto.getConcentratedCheckCode());
                roomHouseFilings.setStatus("1");
                roomHouseFilingsRepository.updateById(roomHouseFilings);
            }else {
                roomHouseFilings = new RoomHouseFilings();
                roomHouseFilings.setRoomHouseId(roomHouse.getId());
                roomHouseFilings.setExternalHouseId(recordInfoDto.getConcentratedExternalHouseId());
                roomHouseFilings.setCheckCode(recordInfoDto.getConcentratedCheckCode());
                roomHouseFilings.setStatus("1");
                roomHouseFilings.setTenantId(roomHouse.getTenantId());
                roomHouseFilingsRepository.save(roomHouseFilings);
            }
        }

        // 更新ES数据
        List<RoomelUpdateReqVO> roomelUpdateReqVOS = new ArrayList<>();
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouse.getId());
        roomelUpdateReqVO.setLayoutId(roomHouse.getLayoutId());
        roomelUpdateReqVO.setLayoutName(roomLayout.getName());
        roomelUpdateReqVO.setFacetoType(roomHouse.getToward());
        roomelUpdateReqVO.setDecoration(roomHouse.getDecoration());
        roomelUpdateReqVO.setToward(roomHouse.getToward());
        roomelUpdateReqVO.setCheckCode(recordInfoDto.getConcentratedCheckCode());
        roomelUpdateReqVO.setRoomUsage(roomHouse.getRoomUsage());
        roomelUpdateReqVO.setSpace(roomHouse.getSpace());
        roomelUpdateReqVOS.add(roomelUpdateReqVO);
        // 更新房源信息到es
        roomEsProducer.updateBatchRoomEl(roomelUpdateReqVOS);

        return CommonResult.success(Boolean.TRUE);
    }

    /**
     * 分散式房源新增
     *
     * @param noConcentratedAddVO
     * @param tenantId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> noConcentratedAdd(NoConcentratedAddVO noConcentratedAddVO, Long tenantId) {
        // 校验公寓信息
        Apartment apartment = apartmentRepository.getById(noConcentratedAddVO.getApartmentId());
        Assert.isTrue(ObjectUtil.isNotEmpty(apartment), "公寓信息不存在");
        if (!ObjectUtil.isAllNotEmpty(apartment.getAddress(), apartment.getIsConcentrated())) {
            throw new ServiceException(new ErrorCode(20034, "请先维护门店信息"));
        }
        if (apartment.getIsConcentrated()) {
            throw new ServiceException(new ErrorCode(20034, "集中式门店无法添加分散式房源"));
        }
        // 面积限制两位小数点
        if (BigDecimal.valueOf(noConcentratedAddVO.getMasterRoomInfo().getSpace()).scale() > 2) {
            throw new ServiceException(new ErrorCode(20044, "面积小数位不能超过两位"));
        }

        String picUrl = noConcentratedAddVO.getPicUrl();
        Assert.isTrue(StrUtil.isEmpty(picUrl) || picUrl.split(",").length <= 8, "房型图片不能超过8张");
        // 如果小区不存在,创建小区, 如果小区存在则查询小区的信息,存入apartment_area
        RoomArea roomArea = this.addRoomArea(
                noConcentratedAddVO.getAreaId(),
                noConcentratedAddVO.getAreaName(),
                noConcentratedAddVO.getProvince(),
                noConcentratedAddVO.getCity(),
                noConcentratedAddVO.getDistrict(),
                noConcentratedAddVO.getStreet(),
                noConcentratedAddVO.getAddress());
        // 检查集中式是否存在该楼栋
        this.checkBuilding(noConcentratedAddVO.getProvince(),
                noConcentratedAddVO.getCity(),
                noConcentratedAddVO.getDistrict(),
                noConcentratedAddVO.getStreet(),
                noConcentratedAddVO.getAddress(),
                noConcentratedAddVO.getAreaName(),
                noConcentratedAddVO.getMasterRoomInfo().getBuildingNo(),
                true);
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.getOne(
                new LambdaQueryWrapper<RoomApartmentArea>()
                        .eq(RoomApartmentArea::getApartmentId, noConcentratedAddVO.getApartmentId())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getProvince()), RoomApartmentArea::getProvince, noConcentratedAddVO.getProvince())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getCity()), RoomApartmentArea::getCity, noConcentratedAddVO.getCity())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getDistrict()), RoomApartmentArea::getDistrict, noConcentratedAddVO.getDistrict())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getStreet()), RoomApartmentArea::getStreet, noConcentratedAddVO.getStreet())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getAddress()), RoomApartmentArea::getAddress, noConcentratedAddVO.getAddress())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getAreaName()), RoomApartmentArea::getArea, noConcentratedAddVO.getAreaName())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getMasterRoomInfo().getBuildingNo()), RoomApartmentArea::getBuildingNo, noConcentratedAddVO.getMasterRoomInfo().getBuildingNo())
                        .eq(ObjectUtil.isNotEmpty(noConcentratedAddVO.getMasterRoomInfo().getUnitNo()), RoomApartmentArea::getUnitNo, noConcentratedAddVO.getMasterRoomInfo().getUnitNo())
        );
        // 判断室号是否重复
        RoomHouse roomHouseResp = roomHouseRepository.getByAddressAndHouseNo(
                noConcentratedAddVO.getProvince(),
                noConcentratedAddVO.getCity(),
                noConcentratedAddVO.getDistrict(),
                noConcentratedAddVO.getStreet(),
                noConcentratedAddVO.getAddress(),
                noConcentratedAddVO.getAreaName(),
                noConcentratedAddVO.getMasterRoomInfo().getBuildingNo(),
                noConcentratedAddVO.getMasterRoomInfo().getUnitNo(),
                noConcentratedAddVO.getMasterRoomInfo().getHouseNo());
        if (ObjectUtil.isNotEmpty(roomHouseResp)) {
            String msg = StrUtil.format("室号{}已在{}门店{}栋{}单元存在,请不要重复添加",
                    roomHouseResp.getHouseNo(),
                    roomHouseResp.getArea(),
                    roomHouseResp.getBuildingNo(),
                    roomHouseResp.getUnitNo());
            throw new ServiceException(new ErrorCode(20056, msg));
        }

        if (ObjectUtil.isEmpty(roomApartmentArea)) {
            // 保存公寓小区信息
            roomApartmentArea = new RoomApartmentArea();
            roomApartmentArea.setApartmentId(noConcentratedAddVO.getApartmentId());
            roomApartmentArea.setRoomAreaId(roomArea.getId());
            roomApartmentArea.setIsConcentrated(false);
            roomApartmentArea.setBuildingNo(noConcentratedAddVO.getMasterRoomInfo().getBuildingNo());
            roomApartmentArea.setUnitNo(noConcentratedAddVO.getMasterRoomInfo().getUnitNo());
            roomApartmentArea.setArea(noConcentratedAddVO.getAreaName());
            roomApartmentArea.setProvince(noConcentratedAddVO.getProvince());
            roomApartmentArea.setCity(noConcentratedAddVO.getCity());
            roomApartmentArea.setDistrict(noConcentratedAddVO.getDistrict());
            roomApartmentArea.setStreet(noConcentratedAddVO.getStreet());
            roomApartmentArea.setAddress(noConcentratedAddVO.getAddress());
            roomApartmentArea.setFloorNum(noConcentratedAddVO.getMasterRoomInfo().getFloorNum());
            roomApartmentArea.setGroundFloorNum(noConcentratedAddVO.getMasterRoomInfo().getGroundFloorNum());
            roomApartmentArea.setLongitude(roomArea.getGeoLng());
            roomApartmentArea.setLatitude(roomArea.getGeoLat());
            roomApartmentArea.setFloorRoomNum(0);
            roomApartmentArea.setRoomNum(1);
            roomApartmentArea.setTenantId(tenantId);
            roomApartmentAreaRepository.save(roomApartmentArea);
        }
        // 备案信息
        RecordInfoDto recordInfoDto = noConcentratedAddVO.getRecordInfoDto();
        RoomHouseInfo roomHouseInfo = RoomHouseInfoConvert.INSTANCE.convert(recordInfoDto);

        // 保存楼层
        RoomFloor roomFloor = new RoomFloor();
        roomFloor.setApartmentId(noConcentratedAddVO.getApartmentId());
        roomFloor.setApartmentAreaId(roomApartmentArea.getId());
        roomFloor.setFloorRoomNum(1);
        roomFloor.setNum(noConcentratedAddVO.getMasterRoomInfo().getInFloorNum());
        roomFloor.setName(noConcentratedAddVO.getMasterRoomInfo().getInFloorNum() + "楼");
        roomFloor.setTenantId(tenantId);
        roomFloorRepository.save(roomFloor);

        // 保存户型
        // 检查户型是否存在
        NoConcentratedAddRoomHouseDto masterRoomInfo = noConcentratedAddVO.getMasterRoomInfo();
        RoomHouseType roomHouseType = houseTypeService.getRoomHouseType(masterRoomInfo.getBedRoomNum(),
                masterRoomInfo.getLivingRoomNum(),
                masterRoomInfo.getToiletNum(),
                masterRoomInfo.getKitchenNum(),
                masterRoomInfo.getBalcony());
        // 保存主房间
        RoomHouse masterRoomHouse = new RoomHouse();
        masterRoomHouse.setId(IdUtil.getSnowflakeNextId());
        masterRoomHouse.setName(noConcentratedAddVO.getMasterRoomInfo().getHouseNo());
        masterRoomHouse.setNo(codeUtil.nextCode("FJ"));
        masterRoomHouse.setProvince(noConcentratedAddVO.getProvince());
        masterRoomHouse.setCity(noConcentratedAddVO.getCity());
        masterRoomHouse.setDistrict(noConcentratedAddVO.getDistrict());
        masterRoomHouse.setAddress(noConcentratedAddVO.getAddress());
        masterRoomHouse.setArea(noConcentratedAddVO.getAreaName());
        masterRoomHouse.setStreet(noConcentratedAddVO.getStreet());
        masterRoomHouse.setSpace(noConcentratedAddVO.getMasterRoomInfo().getSpace());
        masterRoomHouse.setApartmentId(noConcentratedAddVO.getApartmentId());
        masterRoomHouse.setHouseNo(noConcentratedAddVO.getMasterRoomInfo().getHouseNo());
        masterRoomHouse.setIsWhole(noConcentratedAddVO.getIsWhole());
        masterRoomHouse.setRoomNum(noConcentratedAddVO.getSlaveRoomInfo().size());
        masterRoomHouse.setIsStop(false);
        masterRoomHouse.setFloorId(roomFloor.getId());
        masterRoomHouse.setFloorNo(roomFloor.getNum().toString());
        masterRoomHouse.setDecoration(recordInfoDto.getDecoration());
        masterRoomHouse.setToward(noConcentratedAddVO.getMasterRoomInfo().getToward());
        masterRoomHouse.setIsConcentrated(false);
        masterRoomHouse.setApartmentAreaId(roomApartmentArea.getId());
        masterRoomHouse.setRoomHouseTypeId(roomHouseType.getId());
        masterRoomHouse.setPicUrl(noConcentratedAddVO.getPicUrl());
        masterRoomHouse.setVideoUrl(noConcentratedAddVO.getVideoUrl());
        masterRoomHouse.setVrPicUrl(noConcentratedAddVO.getVrPicUrl());
        masterRoomHouse.setVrUrl(noConcentratedAddVO.getVrUrl());
        masterRoomHouse.setPublicFacilities(noConcentratedAddVO.getRoomEquipment());
        masterRoomHouse.setPeopleNum(noConcentratedAddVO.getMasterRoomInfo().getPeopleNum());
        masterRoomHouse.setIsLock(false);
        masterRoomHouse.setDeptId(apartment.getDeptId());
        masterRoomHouse.setBuildingNo(roomApartmentArea.getBuildingNo());
        masterRoomHouse.setUnitNo(roomApartmentArea.getUnitNo());
        masterRoomHouse.setRoomUsage(noConcentratedAddVO.getMasterRoomInfo().getRoomUsage());
        masterRoomHouse.setIsClean(true);
        masterRoomHouse.setIsRepair(false);
        masterRoomHouse.setTenantId(tenantId);
        roomHouseRepository.save(masterRoomHouse);
        // 创建房源时，加入一条空的房态
        RoomStateRecord masterRoomStateRecord = new RoomStateRecord();
        masterRoomStateRecord.setRoomId(masterRoomHouse.getId());
        masterRoomStateRecord.setIsCurrentState(true);
        // 分散式房源创建时,默认状态已冻结
        masterRoomStateRecord.setState(RentStatusEnum.FREEZE.getValue());
        roomStateRecordRepository.save(masterRoomStateRecord);
        // 保存主房间的备案信息
        roomHouseInfo.setRoomHouseId(masterRoomHouse.getId());
        roomHouseInfoRepository.save(roomHouseInfo);
        roomHouseInfo.setId(null);


        List<RoomelCreateReqVO> roomelCreateReqVOS = new ArrayList<>();

        // 组装主房间ES所需数据
        StringBuilder sb = new StringBuilder();
        sb.append(masterRoomHouse.getArea());
        sb.append(roomApartmentArea.getBuildingNo());
        sb.append("栋");
        if (!masterRoomHouse.getIsConcentrated()) {
            sb.append(roomApartmentArea.getUnitNo());
            sb.append("单元");
        }
        sb.append(masterRoomHouse.getName());
        String fullName = sb.toString();
        RoomelCreateReqVO masterRoomelCreateReqVO = new RoomelCreateReqVO();
        masterRoomelCreateReqVO.setId(masterRoomHouse.getId());
        masterRoomelCreateReqVO.setFullName(fullName);
        masterRoomelCreateReqVO.setApartmentAreaId(roomApartmentArea.getId());
        masterRoomelCreateReqVO.setApartmentAreaName(roomApartmentArea.getArea());
        masterRoomelCreateReqVO.setApartmentName(apartment.getName());
        masterRoomelCreateReqVO.setApartmentId(apartment.getId());
        masterRoomelCreateReqVO.setIsConcentrated(roomApartmentArea.getIsConcentrated());
        masterRoomelCreateReqVO.setApartmentAreaLat(roomArea.getGeoLat());
        masterRoomelCreateReqVO.setApartmentAreaLon(roomArea.getGeoLng());
        masterRoomelCreateReqVO.setApartmentLat(apartment.getLatitude());
        masterRoomelCreateReqVO.setApartmentLon(apartment.getLongitude());
        masterRoomelCreateReqVO.setSourceType(apartment.getSourceType());
        masterRoomelCreateReqVO.setFloorId(masterRoomHouse.getFloorId());
        masterRoomelCreateReqVO.setBuildingNo(roomApartmentArea.getBuildingNo());
        masterRoomelCreateReqVO.setUnitNo(roomApartmentArea.getUnitNo());
        masterRoomelCreateReqVO.setFloorNo(Integer.valueOf(masterRoomHouse.getFloorNo()));
        masterRoomelCreateReqVO.setFloorSum(roomApartmentArea.getFloorNum());
        masterRoomelCreateReqVO.setCity(roomApartmentArea.getCity());
        masterRoomelCreateReqVO.setDistrict(roomApartmentArea.getDistrict());
        masterRoomelCreateReqVO.setStreet(roomApartmentArea.getStreet());
        masterRoomelCreateReqVO.setAddress(roomApartmentArea.getAddress());
        masterRoomelCreateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
        masterRoomelCreateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
        masterRoomelCreateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
        masterRoomelCreateReqVO.setToiletNum(roomHouseType.getToiletNum());
        masterRoomelCreateReqVO.setBalcony(roomHouseType.getBalcony());
        masterRoomelCreateReqVO.setRoomHouseTypeId(roomHouseType.getId());
        masterRoomelCreateReqVO.setRoomHouseTypeName(roomHouseType.getName());
        masterRoomelCreateReqVO.setFacetoType(masterRoomHouse.getToward());
        masterRoomelCreateReqVO.setIsWhole(masterRoomHouse.getIsWhole());
        masterRoomelCreateReqVO.setSpace(masterRoomHouse.getSpace());
        masterRoomelCreateReqVO.setDecoration(masterRoomHouse.getDecoration());
        // 分散式房源创建时,默认状态已冻结
        masterRoomelCreateReqVO.setHouseState(RentStatusEnum.FREEZE.getValue());
        masterRoomelCreateReqVO.setRoomHouseName(masterRoomHouse.getName());
        masterRoomelCreateReqVO.setIsScheduled(false);
        masterRoomelCreateReqVO.setTenantId(tenantId);
        masterRoomelCreateReqVO.setRoomHouseNo(masterRoomHouse.getNo());
        masterRoomelCreateReqVO.setHouseNo(masterRoomHouse.getHouseNo());
        masterRoomelCreateReqVO.setIsLock(false);
        masterRoomelCreateReqVO.setIsStop(false);
        masterRoomelCreateReqVO.setPublicFacilities(masterRoomHouse.getPublicFacilities());
        masterRoomelCreateReqVO.setCreateTime(LocalDateTime.now());
        masterRoomelCreateReqVO.setDeptId(masterRoomHouse.getDeptId());
        masterRoomelCreateReqVO.setRoomAreaId(roomApartmentArea.getRoomAreaId());
        masterRoomelCreateReqVO.setToward(masterRoomHouse.getToward());
        masterRoomelCreateReqVO.setIsClean(true);
        masterRoomelCreateReqVO.setIsRepair(false);
        masterRoomelCreateReqVO.setRoomUsage(masterRoomHouse.getRoomUsage());
        roomelCreateReqVOS.add(masterRoomelCreateReqVO);

        // 保存子房间房间
        List<NoConcentratedRoomInfoDto> roomInfos = noConcentratedAddVO.getSlaveRoomInfo();

        NoConcentratedRoomInfoDto noConcentratedRoomInfoDto = roomInfos.stream().filter(p -> p.getRoomHouseNo().equals(noConcentratedAddVO.getMasterRoomInfo().getHouseNo())).findFirst().orElse(null);
        if (ObjectUtil.isNotEmpty(noConcentratedRoomInfoDto)) {
            throw new ServiceException(new ErrorCode(20002, "房间名不能和室号重复"));
        }
        List<String> roomNames = roomInfos.stream().map(NoConcentratedRoomInfoDto::getRoomHouseNo).distinct().collect(Collectors.toList());
        if (roomNames.size() < roomInfos.size()) {
            throw new ServiceException(new ErrorCode(20001, "房间名不能重复"));
        }

        Assert.isFalse(noConcentratedAddVO.getIsWhole() && ObjectUtil.isNotEmpty(roomInfos), "整租时不能添加子房间");
        RoomApartmentArea finalRoomApartmentArea = roomApartmentArea;
        RoomHouseType finalRoomHouseType = roomHouseType;
        roomInfos.stream().forEach(roomInfo -> {
            RoomHouse roomHouse = new RoomHouse();
            roomHouse.setId(IdUtil.getSnowflakeNextId());
            roomHouse.setName(masterRoomHouse.getName() + "-" + roomInfo.getRoomHouseNo());
            roomHouse.setNo(codeUtil.nextCode("FJ"));
            roomHouse.setProvince(noConcentratedAddVO.getProvince());
            roomHouse.setCity(noConcentratedAddVO.getCity());
            roomHouse.setDistrict(noConcentratedAddVO.getDistrict());
            roomHouse.setStreet(noConcentratedAddVO.getStreet());
            roomHouse.setAddress(noConcentratedAddVO.getAddress());
            roomHouse.setArea(noConcentratedAddVO.getAreaName());
            roomHouse.setSpace(roomInfo.getSpace());
            roomHouse.setApartmentId(noConcentratedAddVO.getApartmentId());
            roomHouse.setHouseNo(roomInfo.getRoomHouseNo());
            roomHouse.setIsWhole(noConcentratedAddVO.getIsWhole());
            roomHouse.setRoomNum(roomInfos.size());
            roomHouse.setIsStop(false);
            roomHouse.setFloorId(roomFloor.getId());
            roomHouse.setFloorNo(roomFloor.getNum().toString());
            roomHouse.setDecoration(recordInfoDto.getDecoration());
            roomHouse.setToward(roomInfo.getToward());
            roomHouse.setIsConcentrated(false);
            roomHouse.setApartmentAreaId(finalRoomApartmentArea.getId());
            roomHouse.setRoomHouseTypeId(finalRoomHouseType.getId());
            roomHouse.setSuperId(masterRoomHouse.getId());
            roomHouse.setPeopleNum(roomInfo.getPeopleNum());
            roomHouse.setRoomType(roomInfo.getRoomType());
            roomHouse.setIsLock(false);
            roomHouse.setDeptId(apartment.getDeptId());
            roomHouse.setBuildingNo(finalRoomApartmentArea.getBuildingNo());
            roomHouse.setUnitNo(finalRoomApartmentArea.getUnitNo());
            roomHouse.setPicUrl(noConcentratedAddVO.getPicUrl());
            roomHouse.setVideoUrl(noConcentratedAddVO.getVideoUrl());
            roomHouse.setVrPicUrl(noConcentratedAddVO.getVrPicUrl());
            roomHouse.setVrUrl(noConcentratedAddVO.getVrUrl());
            roomHouse.setRoomUsage(noConcentratedAddVO.getMasterRoomInfo().getRoomUsage());
            roomHouse.setIsClean(true);
            roomHouse.setIsRepair(false);
            roomHouseRepository.save(roomHouse);

            // 创建房源时，加入一条空的房态
            RoomStateRecord roomStateRecord = new RoomStateRecord();
            roomStateRecord.setRoomId(roomHouse.getId());
            roomStateRecord.setIsCurrentState(true);
            roomStateRecord.setState(RentStatusEnum.FREEZE.getValue());
            roomStateRecordRepository.save(roomStateRecord);

            roomHouseInfo.setRoomHouseId(roomHouse.getId());
            roomHouseInfo.setId(null);
            roomHouseInfoRepository.save(roomHouseInfo);

            // 组装ES所需数据
            StringBuilder name = new StringBuilder();
            name.append(roomHouse.getArea());
            name.append(finalRoomApartmentArea.getBuildingNo());
            name.append("栋");
            if (!roomHouse.getIsConcentrated()) {
                name.append(finalRoomApartmentArea.getUnitNo());
                name.append("单元");
            }
            name.append(roomHouse.getName());

            RoomelCreateReqVO roomelCreateReqVO = new RoomelCreateReqVO();
            roomelCreateReqVO.setId(roomHouse.getId());
            roomelCreateReqVO.setFullName(name.toString());
            roomelCreateReqVO.setSuperId(roomHouse.getSuperId());
            roomelCreateReqVO.setApartmentAreaId(finalRoomApartmentArea.getId());
            roomelCreateReqVO.setApartmentAreaName(finalRoomApartmentArea.getArea());
            roomelCreateReqVO.setApartmentName(apartment.getName());
            roomelCreateReqVO.setApartmentId(apartment.getId());
            roomelCreateReqVO.setIsConcentrated(finalRoomApartmentArea.getIsConcentrated());
            roomelCreateReqVO.setApartmentAreaLat(roomArea.getGeoLat());
            roomelCreateReqVO.setApartmentAreaLon(roomArea.getGeoLng());
            roomelCreateReqVO.setApartmentLat(apartment.getLatitude());
            roomelCreateReqVO.setApartmentLon(apartment.getLongitude());
            roomelCreateReqVO.setSourceType(apartment.getSourceType());
            roomelCreateReqVO.setFloorId(roomHouse.getFloorId());
            roomelCreateReqVO.setBuildingNo(finalRoomApartmentArea.getBuildingNo());
            roomelCreateReqVO.setUnitNo(finalRoomApartmentArea.getUnitNo());
            roomelCreateReqVO.setFloorNo(Integer.valueOf(roomHouse.getFloorNo()));
            roomelCreateReqVO.setFloorSum(finalRoomApartmentArea.getFloorNum());
            roomelCreateReqVO.setCity(finalRoomApartmentArea.getCity());
            roomelCreateReqVO.setDistrict(finalRoomApartmentArea.getDistrict());
            roomelCreateReqVO.setStreet(finalRoomApartmentArea.getStreet());
            roomelCreateReqVO.setAddress(finalRoomApartmentArea.getAddress());
            roomelCreateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
            roomelCreateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
            roomelCreateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
            roomelCreateReqVO.setToiletNum(roomHouseType.getToiletNum());
            roomelCreateReqVO.setBalcony(roomHouseType.getBalcony());
            roomelCreateReqVO.setRoomHouseTypeId(roomHouseType.getId());
            roomelCreateReqVO.setRoomHouseTypeName(roomHouseType.getName());
            roomelCreateReqVO.setFacetoType(roomHouse.getToward());
            roomelCreateReqVO.setIsWhole(roomHouse.getIsWhole());
            roomelCreateReqVO.setSpace(roomHouse.getSpace());
            roomelCreateReqVO.setDecoration(roomHouse.getDecoration());
            roomelCreateReqVO.setHouseState(RentStatusEnum.FREEZE.getValue());
            roomelCreateReqVO.setRoomHouseName(roomHouse.getName());
            roomelCreateReqVO.setIsScheduled(false);
            roomelCreateReqVO.setTenantId(tenantId);
            roomelCreateReqVO.setRoomHouseNo(roomHouse.getNo());
            roomelCreateReqVO.setHouseNo(roomHouse.getHouseNo());
            roomelCreateReqVO.setIsLock(false);
            roomelCreateReqVO.setIsStop(false);
            // 引用主房源的独立设施
            roomelCreateReqVO.setPublicFacilities(masterRoomHouse.getPublicFacilities());
            roomelCreateReqVO.setCreateTime(LocalDateTime.now());
            roomelCreateReqVO.setDeptId(roomHouse.getDeptId());
            roomelCreateReqVO.setRoomType(roomHouse.getRoomType());
            roomelCreateReqVO.setRoomAreaId(finalRoomApartmentArea.getRoomAreaId());
            roomelCreateReqVO.setToward(roomHouse.getToward());
            roomelCreateReqVO.setRoomUsage(noConcentratedAddVO.getMasterRoomInfo().getRoomUsage());
            roomelCreateReqVO.setIsClean(true);
            roomelCreateReqVO.setIsRepair(false);
            roomelCreateReqVOS.add(roomelCreateReqVO);
        });
        // 推送房源信息到es
        roomEsProducer.ListAddRoomEl(roomelCreateReqVOS);
        // 推送备案信息
        sendFilings(tenantId, roomApartmentArea, roomHouseInfo, roomHouseType, masterRoomHouse, roomInfos);

        return CommonResult.success(Boolean.TRUE);
    }

    private void checkBuilding(String province, String city, String district, String street, String address, String areaName, String buildingNo, Boolean isConcentrated) {
        List<RoomApartmentArea> roomApartmentAreas = roomApartmentAreaRepository.list(
                new LambdaQueryWrapper<RoomApartmentArea>()
                        .eq(RoomApartmentArea::getIsConcentrated, isConcentrated)
                        .eq(ObjectUtil.isNotEmpty(province), RoomApartmentArea::getProvince, province)
                        .eq(ObjectUtil.isNotEmpty(city), RoomApartmentArea::getCity, city)
                        .eq(ObjectUtil.isNotEmpty(district), RoomApartmentArea::getDistrict, district)
                        .eq(ObjectUtil.isNotEmpty(street), RoomApartmentArea::getStreet, street)
                        .eq(ObjectUtil.isNotEmpty(address), RoomApartmentArea::getAddress, address)
                        .eq(ObjectUtil.isNotEmpty(areaName), RoomApartmentArea::getArea, areaName)
                        .eq(ObjectUtil.isNotEmpty(buildingNo), RoomApartmentArea::getBuildingNo, buildingNo)
        );
        if (ObjectUtil.isNotEmpty(roomApartmentAreas)) {
            String st = isConcentrated ? "集中式" : "分散式";
            throw new ServiceException(new ErrorCode(30044, st + "已存在该楼栋,请不要重复添加"));
        }
    }

    private void sendFilings(Long tenantId, RoomApartmentArea roomApartmentArea, RoomHouseInfo roomHouseInfo, RoomHouseType roomHouseType, RoomHouse masterRoomHouse, List<NoConcentratedRoomInfoDto> roomInfos) {
        // 推送备案信息 - 房源
        InventoryCheckBo bo = new InventoryCheckBo();
        bo.setUniqueDataId(masterRoomHouse.getId().toString());
        bo.setSecretKey(filingsProperties.getSecretKey());
        bo.setOwnerName(roomHouseInfo.getOwnerName());
        bo.setCardType(Integer.valueOf(roomHouseInfo.getCardType()));
        bo.setCardNo(roomHouseInfo.getCardNo());
        bo.setTelPhone(roomHouseInfo.getTelPhone());
        bo.setPropertyNo(roomHouseInfo.getPropertyNo());
        bo.setPropertyType(Integer.valueOf(roomHouseInfo.getPropertyType()));
        bo.setRegion(masterRoomHouse.getDistrict())
                .setStreetName(masterRoomHouse.getStreet())
                .setItemName(masterRoomHouse.getArea())
                .setBuildNo(roomApartmentArea.getBuildingNo() + "栋" + roomApartmentArea.getUnitNo() + "单元")
                .setRoomNo(masterRoomHouse.getHouseNo())
                .setHouseStructure(Integer.valueOf(roomHouseInfo.getHouseStructure()))
                .setHouseArea(masterRoomHouse.getSpace())
                // 房源户型 1-一户室，2-二户室，3-三户室，4-四户室，5-四户室以上
                .setHouseType(roomHouseType.getBedRoomNum())
                .setHouseOrientation(Integer.valueOf(masterRoomHouse.getToward()))
                .setRenovation(Integer.valueOf(masterRoomHouse.getDecoration()))
                .setRegisterType(Integer.valueOf(roomHouseInfo.getRegisterType()));
        RoomHouseFilings filings = roomHouseFilingsRepository.getByRoomHouseId(masterRoomHouse.getId());
        if (ObjectUtil.isNotEmpty(filings)) {
            bo.setHouseId(filings.getExternalHouseId());
        }
        InventoryRoomCheckBo roomCheckBo = new InventoryRoomCheckBo();
        roomCheckBo.setSecretKey(filingsProperties.getSecretKey());
        roomCheckBo.setOperationType(1);
        roomCheckBo.setUniqueDataId(masterRoomHouse.getId().toString());
        roomCheckBo.setRentalMode(2);
        List<InventoryRoomCheckBo.HouseRoom> rooms = new ArrayList<>();
        roomInfos.stream().forEach(roomInfo -> {
            InventoryRoomCheckBo.HouseRoom houseRoom = new InventoryRoomCheckBo.HouseRoom().setRoomName(roomInfo.getRoomHouseNo()).setRoomArea(roomInfo.getSpace());
            RoomHouseFilings roomFilings = roomHouseFilingsRepository.getByRoomHouseId(roomInfo.getRoomHouseId());
            if (ObjectUtil.isNotEmpty(roomFilings)) {
                houseRoom.setHouseId(roomFilings.getExternalHouseId());
            }
            rooms.add(houseRoom);
        });

        roomCheckBo.setLeaseSubHouseSets(rooms);
        publisher.publishEvent(new InventoryCheckEvent(this, bo, roomCheckBo, tenantId));
    }

    /**
     * 分散式编辑房源信息
     *
     * @param editReqVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> noConcentratedEdit(NoConcentratedRoomHouseEditReqVO editReqVO) {
        // 校验公寓信息
        RoomHouse masterRoomHouse = roomHouseRepository.getById(editReqVO.getRoomHouseId());
        Assert.isTrue(ObjectUtil.isNotEmpty(masterRoomHouse), "房源信息不存在");
        // 如果是合租的子房间
        if (!editReqVO.getIsWhole() && ObjectUtil.isNotEmpty(masterRoomHouse.getSuperId())) {
            masterRoomHouse = roomHouseRepository.getById(masterRoomHouse.getSuperId());
        }

        Apartment apartment = apartmentRepository.getById(masterRoomHouse.getApartmentId());
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.getById(masterRoomHouse.getApartmentAreaId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomApartmentArea), "小区信息不存在");
        // 面积限制两位小数点
        if (BigDecimal.valueOf(editReqVO.getMasterRoomInfo().getSpace()).scale() > 2) {
            throw new ServiceException(new ErrorCode(20044, "面积小数位不能超过两位"));
        }
        String picUrl = editReqVO.getPicUrl();
        Assert.isTrue(StrUtil.isEmpty(picUrl) || picUrl.split(",").length <= 8, "房型图片不能超过8张");
        RoomArea roomArea = roomAreaRepository.getById(roomApartmentArea.getRoomAreaId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomArea), "小区信息不存在");
        // 检查户型是否存在
        NoConcentratedEditRoomHouseDto masterRoomInfo = editReqVO.getMasterRoomInfo();
        RoomHouseType roomHouseType = houseTypeService.getRoomHouseType(masterRoomInfo.getBedRoomNum(),
                masterRoomInfo.getLivingRoomNum(),
                masterRoomInfo.getToiletNum(),
                masterRoomInfo.getKitchenNum(),
                masterRoomInfo.getBalcony());
        // 修改主房间信息
        masterRoomHouse.setRoomHouseTypeId(roomHouseType.getId());
        masterRoomHouse.setSpace(editReqVO.getMasterRoomInfo().getSpace());
        masterRoomHouse.setToward(editReqVO.getMasterRoomInfo().getToward());
        masterRoomHouse.setPicUrl(editReqVO.getPicUrl());
        masterRoomHouse.setVideoUrl(editReqVO.getVideoUrl());
        masterRoomHouse.setVrUrl(editReqVO.getVrUrl());
        masterRoomHouse.setVrPicUrl(editReqVO.getVrPicUrl());
        masterRoomHouse.setPublicFacilities(editReqVO.getRoomEquipment());
        masterRoomHouse.setPeopleNum(editReqVO.getMasterRoomInfo().getPeopleNum());
        masterRoomHouse.setDecoration(editReqVO.getRecordInfoDto().getDecoration());
        masterRoomHouse.setRoomUsage(editReqVO.getMasterRoomInfo().getRoomUsage());
        roomHouseRepository.updateById(masterRoomHouse);

        // 更新ES数据
        List<RoomelUpdateReqVO> roomelUpdateReqVOS = new ArrayList<>();
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(masterRoomHouse.getId());
        roomelUpdateReqVO.setRoomHouseTypeId(masterRoomHouse.getRoomHouseTypeId());
        roomelUpdateReqVO.setRoomHouseTypeName(roomHouseType.getName());
        roomelUpdateReqVO.setSpace(masterRoomHouse.getSpace());
        roomelUpdateReqVO.setDecoration(masterRoomHouse.getDecoration());
        roomelUpdateReqVO.setPublicFacilities(masterRoomHouse.getPublicFacilities());
        roomelUpdateReqVO.setBedroomNum(masterRoomInfo.getBedRoomNum());
        roomelUpdateReqVO.setLivingroomNum(masterRoomInfo.getLivingRoomNum());
        roomelUpdateReqVO.setToiletNum(masterRoomInfo.getToiletNum());
        roomelUpdateReqVO.setKitchenNum(masterRoomInfo.getKitchenNum());
        roomelUpdateReqVO.setBalcony(masterRoomInfo.getBalcony());
        roomelUpdateReqVO.setToward(masterRoomInfo.getToward());
        roomelUpdateReqVO.setRoomUsage(masterRoomHouse.getRoomUsage());
        roomelUpdateReqVOS.add(roomelUpdateReqVO);

        // 查询备案信息
        RoomHouseInfo roomHouseInfo = roomHouseInfoRepository.getByRoomHouseId(masterRoomHouse.getId());
        if (ObjectUtil.isEmpty(roomHouseInfo)) {
            roomHouseInfo = new RoomHouseInfo();
        }
        // 更新备案信息
        RecordInfoDto recordInfoDto = editReqVO.getRecordInfoDto();
        BeanUtil.copyProperties(recordInfoDto, roomHouseInfo);
        roomHouseInfo.setRoomHouseId(masterRoomHouse.getId());
        roomHouseInfoRepository.updateById(roomHouseInfo);
        roomHouseInfo.setId(null);

        // 子房间
        List<NoConcentratedRoomInfoDto> roomInfos = editReqVO.getSlaveRoomInfo();
        List<RoomelCreateReqVO> roomelCreateReqVOS = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        RoomHouseInfo finalRoomHouseInfo = roomHouseInfo;
        RoomHouse finalMasterRoomHouse = masterRoomHouse;
        List<RoomHouse> slaveRoomHouses = new ArrayList<>();
        roomInfos.stream().forEach(roomInfo -> {
            // 修改子房间
            if (ObjectUtil.isNotEmpty(roomInfo.getRoomHouseId())) {
                ids.add(roomInfo.getRoomHouseId());
                RoomHouse roomHouse = roomHouseRepository.getById(roomInfo.getRoomHouseId());
                roomHouse.setName(finalMasterRoomHouse.getName() + "-" + roomInfo.getRoomHouseNo());
                roomHouse.setHouseNo(roomInfo.getRoomHouseNo());
                roomHouse.setRoomType(roomInfo.getRoomType());
                roomHouse.setSpace(roomInfo.getSpace());
                roomHouse.setToward(roomInfo.getToward());
                roomHouse.setPeopleNum(roomInfo.getPeopleNum());
                roomHouse.setDecoration(recordInfoDto.getDecoration());
                roomHouse.setPicUrl(editReqVO.getPicUrl());
                roomHouse.setVideoUrl(editReqVO.getVideoUrl());
                roomHouse.setVrUrl(editReqVO.getVrUrl());
                roomHouse.setVrPicUrl(editReqVO.getVrPicUrl());
                roomHouse.setRoomUsage(editReqVO.getMasterRoomInfo().getRoomUsage());
                roomHouse.setRoomHouseTypeId(roomHouseType.getId());
                roomHouseRepository.updateById(roomHouse);
                slaveRoomHouses.add(roomHouse);
                // 修改子房间的备案信息
                RoomHouseInfo houseInfo = roomHouseInfoRepository.getByRoomHouseId(roomHouse.getId());
                if (ObjectUtil.isEmpty(houseInfo)) {
                    houseInfo = new RoomHouseInfo();
                }
                // 更新备案信息
                BeanUtil.copyProperties(recordInfoDto, houseInfo);
                houseInfo.setRoomHouseId(roomHouse.getId());
                roomHouseInfoRepository.updateById(houseInfo);
                // 同步修改ES数据
                StringBuilder name = new StringBuilder();
                name.append(roomHouse.getArea());
                name.append(roomApartmentArea.getBuildingNo());
                name.append("栋");
                if (!roomHouse.getIsConcentrated()) {
                    name.append(roomApartmentArea.getUnitNo());
                    name.append("单元");
                }
                name.append(roomHouse.getName());

                RoomelUpdateReqVO slaveRoomelUpdateReqVO = new RoomelUpdateReqVO();
                slaveRoomelUpdateReqVO.setId(roomHouse.getId());
                slaveRoomelUpdateReqVO.setFullName(name.toString());
                slaveRoomelUpdateReqVO.setRoomHouseName(roomHouse.getName());
                slaveRoomelUpdateReqVO.setSpace(roomHouse.getSpace());
                slaveRoomelUpdateReqVO.setFacetoType(roomHouse.getToward());
                slaveRoomelUpdateReqVO.setDecoration(roomHouse.getDecoration());
                slaveRoomelUpdateReqVO.setPublicFacilities(finalMasterRoomHouse.getPublicFacilities());
                slaveRoomelUpdateReqVO.setToward(finalMasterRoomHouse.getToward());
                slaveRoomelUpdateReqVO.setRoomUsage(roomHouse.getRoomUsage());
                slaveRoomelUpdateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
                slaveRoomelUpdateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
                slaveRoomelUpdateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
                slaveRoomelUpdateReqVO.setToiletNum(roomHouseType.getToiletNum());
                slaveRoomelUpdateReqVO.setBalcony(roomHouseType.getBalcony());
                slaveRoomelUpdateReqVO.setRoomHouseTypeId(roomHouseType.getId());
                slaveRoomelUpdateReqVO.setRoomHouseTypeName(roomHouseType.getName());
                roomelUpdateReqVOS.add(slaveRoomelUpdateReqVO);
            } else {
                // 新增的子房间
                RoomHouse roomHouse = new RoomHouse();
                roomHouse.setId(IdUtil.getSnowflakeNextId());
                roomHouse.setName(finalMasterRoomHouse.getName() + "-" + roomInfo.getRoomHouseNo());
                roomHouse.setNo(codeUtil.nextCode("FJ"));
                roomHouse.setProvince(editReqVO.getProvince());
                roomHouse.setCity(editReqVO.getCity());
                roomHouse.setDistrict(editReqVO.getDistrict());
                roomHouse.setStreet(editReqVO.getStreet());
                roomHouse.setAddress(editReqVO.getAddress());
                roomHouse.setArea(editReqVO.getAreaName());
                roomHouse.setSpace(roomInfo.getSpace());
                roomHouse.setApartmentId(finalMasterRoomHouse.getApartmentId());
                roomHouse.setHouseNo(roomInfo.getRoomHouseNo());
                roomHouse.setIsWhole(editReqVO.getIsWhole());
                roomHouse.setRoomNum(roomInfos.size());
                roomHouse.setIsStop(false);
                roomHouse.setIsLock(false);
                roomHouse.setFloorId(finalMasterRoomHouse.getFloorId());
                roomHouse.setFloorNo(finalMasterRoomHouse.getFloorNo());
                roomHouse.setTenantId(finalMasterRoomHouse.getTenantId());
                roomHouse.setDecoration(recordInfoDto.getDecoration());
                roomHouse.setToward(roomInfo.getToward());
                roomHouse.setIsConcentrated(false);
                roomHouse.setApartmentAreaId(finalMasterRoomHouse.getApartmentAreaId());
                roomHouse.setRoomHouseTypeId(roomHouseType.getId());
                roomHouse.setSuperId(finalMasterRoomHouse.getId());
                roomHouse.setPeopleNum(roomInfo.getPeopleNum());
                roomHouse.setRoomType(roomInfo.getRoomType());
                roomHouse.setPicUrl(editReqVO.getPicUrl());
                roomHouse.setVideoUrl(editReqVO.getVideoUrl());
                roomHouse.setVrUrl(editReqVO.getVrUrl());
                roomHouse.setVrPicUrl(editReqVO.getVrPicUrl());
                roomHouse.setRoomUsage(editReqVO.getMasterRoomInfo().getRoomUsage());
                roomHouse.setBuildingNo(finalMasterRoomHouse.getBuildingNo());
                roomHouse.setUnitNo(finalMasterRoomHouse.getUnitNo());
                roomHouse.setDeptId(finalMasterRoomHouse.getDeptId());
                roomHouseRepository.save(roomHouse);
                slaveRoomHouses.add(roomHouse);
                ids.add(roomHouse.getId());

                // 创建房源时，加入一条冻结房态
                RoomStateRecord roomStateRecord = new RoomStateRecord();
                roomStateRecord.setRoomId(roomHouse.getId());
                roomStateRecord.setIsCurrentState(true);
                roomStateRecord.setState(RentStatusEnum.FREEZE.getValue());
                roomStateRecordRepository.save(roomStateRecord);

                // 保存新增子房间的备案信息
                finalRoomHouseInfo.setRoomHouseId(roomHouse.getId());
                roomHouseInfoRepository.save(finalRoomHouseInfo);
                finalRoomHouseInfo.setId(null);
                // 新增ES房源数据
                StringBuilder name = new StringBuilder();
                name.append(roomHouse.getArea());
                name.append(roomApartmentArea.getBuildingNo());
                name.append("栋");
                if (!roomHouse.getIsConcentrated()) {
                    name.append(roomApartmentArea.getUnitNo());
                    name.append("单元");
                }
                name.append(roomHouse.getName());
                RoomelCreateReqVO roomelCreateReqVO = new RoomelCreateReqVO();
                roomelCreateReqVO.setId(roomHouse.getId());
                roomelCreateReqVO.setFullName(name.toString());
                roomelCreateReqVO.setSuperId(roomHouse.getSuperId());
                roomelCreateReqVO.setApartmentAreaId(roomApartmentArea.getId());
                roomelCreateReqVO.setApartmentAreaName(roomApartmentArea.getArea());
                roomelCreateReqVO.setApartmentName(apartment.getName());
                roomelCreateReqVO.setApartmentId(apartment.getId());
                roomelCreateReqVO.setIsConcentrated(roomApartmentArea.getIsConcentrated());
                roomelCreateReqVO.setApartmentAreaLat(roomArea.getGeoLat());
                roomelCreateReqVO.setApartmentAreaLon(roomArea.getGeoLng());
                roomelCreateReqVO.setApartmentLat(apartment.getLatitude());
                roomelCreateReqVO.setApartmentLon(apartment.getLongitude());
                roomelCreateReqVO.setSourceType(apartment.getSourceType());
                roomelCreateReqVO.setFloorId(roomHouse.getFloorId());
                roomelCreateReqVO.setBuildingNo(roomApartmentArea.getBuildingNo());
                roomelCreateReqVO.setUnitNo(roomApartmentArea.getUnitNo());
                roomelCreateReqVO.setFloorNo(Integer.valueOf(roomHouse.getFloorNo()));
                roomelCreateReqVO.setFloorSum(roomApartmentArea.getFloorNum());
                roomelCreateReqVO.setCity(roomApartmentArea.getCity());
                roomelCreateReqVO.setDistrict(roomApartmentArea.getDistrict());
                roomelCreateReqVO.setStreet(roomApartmentArea.getStreet());
                roomelCreateReqVO.setAddress(roomApartmentArea.getAddress());
                roomelCreateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
                roomelCreateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
                roomelCreateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
                roomelCreateReqVO.setToiletNum(roomHouseType.getToiletNum());
                roomelCreateReqVO.setBalcony(roomHouseType.getBalcony());
                roomelCreateReqVO.setRoomHouseTypeId(roomHouseType.getId());
                roomelCreateReqVO.setRoomHouseTypeName(roomHouseType.getName());
                roomelCreateReqVO.setFacetoType(roomHouse.getToward());
                roomelCreateReqVO.setIsWhole(roomHouse.getIsWhole());
                roomelCreateReqVO.setSpace(roomHouse.getSpace());
                roomelCreateReqVO.setDecoration(roomHouse.getDecoration());
                roomelCreateReqVO.setHouseState(RentStatusEnum.FREEZE.getValue());
                roomelCreateReqVO.setRoomHouseName(roomHouse.getName());
                roomelCreateReqVO.setIsScheduled(false);
                roomelCreateReqVO.setTenantId(roomApartmentArea.getTenantId());
                roomelCreateReqVO.setRoomHouseNo(roomHouse.getNo());
                roomelCreateReqVO.setHouseNo(roomHouse.getHouseNo());
                roomelCreateReqVO.setIsLock(false);
                roomelCreateReqVO.setIsStop(false);
                // 引用主房源的独立设施
                roomelCreateReqVO.setPublicFacilities(finalMasterRoomHouse.getPublicFacilities());
                roomelCreateReqVO.setCreateTime(LocalDateTime.now());
                roomelCreateReqVO.setDeptId(roomHouse.getDeptId());
                roomelCreateReqVO.setRoomType(roomHouse.getRoomType());
                roomelCreateReqVO.setRoomAreaId(roomApartmentArea.getRoomAreaId());
                roomelCreateReqVO.setToward(roomHouse.getToward());
                roomelCreateReqVO.setRoomUsage(roomHouse.getRoomUsage());
                roomelCreateReqVOS.add(roomelCreateReqVO);
            }
        });

        // 如果是合租，需要找出主卧/次卧
        RoomHouse roomHouse = new RoomHouse();
        if(!masterRoomHouse.getIsWhole()){
            // 处理主房源资产, 主房源资产优先挂到主卧，其次次卧
            roomHouse = slaveRoomHouses.stream().filter(p -> RoomTypeEnum.ZW.getValue().equals(p.getRoomType())).findFirst().orElse(null);
            if(ObjectUtil.isEmpty(roomHouse)){
                roomHouse = slaveRoomHouses.stream().filter(p -> RoomTypeEnum.CW.getValue().equals(p.getRoomType())).findFirst().orElse(null);
            }
            if(ObjectUtil.isEmpty(roomHouse)){
                throw new ServiceException(SWITCH_RENTAL_FORMATS_ERROR);
            }
        }

        for (RoomHouse slaveRoomHouse : slaveRoomHouses) {
            if(!ids.contains(slaveRoomHouse.getId())){
                // 说明是被删除的房间
                slaveRoomHouse.setIsStop(true);
                slaveRoomHouse.setIsLastStop(true);
                roomHouseRepository.updateById(slaveRoomHouse);

                // 合租需要更新资产信息
                if(!masterRoomHouse.getIsWhole()){
                    // 被删除房源的资产
                    List<RoomEquipment> roomEquipments = roomEquipmentRepository.getByRoomIds(Arrays.asList(slaveRoomHouse.getId()));
                    // 全部归属到主卧/次卧上
                    Long roomHouseId = roomHouse.getId();
                    roomEquipments.stream().forEach(p -> p.setRoomId(roomHouseId));
                    roomEquipmentRepository.updateBatchById(roomEquipments);
                }

                RoomelUpdateReqVO slaveRoomelUpdateReqVO = new RoomelUpdateReqVO();
                slaveRoomelUpdateReqVO.setId(slaveRoomHouse.getId());
                slaveRoomelUpdateReqVO.setIsStop(true);
                roomelUpdateReqVOS.add(slaveRoomelUpdateReqVO);
            }
        }
        // 推送房源信息到es
        if (ObjectUtil.isNotEmpty(roomelCreateReqVOS)) {
            roomEsProducer.ListAddRoomEl(roomelCreateReqVOS);
        }
        // 更新房源信息到es
        if (ObjectUtil.isNotEmpty(roomelUpdateReqVOS)) {
            roomEsProducer.updateBatchRoomEl(roomelUpdateReqVOS);
        }
        // 需要停用的子房间
//        List<RoomHouse> roomHouses = roomHouseRepository.getBySuperId(masterRoomHouse.getId()).getCheckedData();
//        List<Long> roomInfoIds = roomInfos.stream().map(NoConcentratedRoomInfoDto::getRoomHouseId).collect(Collectors.toList());
//        List<RoomHouse> delRoomHouses = roomHouses.stream().filter(p -> !roomInfoIds.contains(p.getId())).collect(Collectors.toList());
//        delRoomHouses.forEach(p -> p.setIsStop(true));
//        roomHouseRepository.updateBatchById(delRoomHouses);

        // 备案信息推送监管平台更新数据
        // 更新监管平台备案信息
        sendFilings(masterRoomHouse.getTenantId(), roomApartmentArea, roomHouseInfo, roomHouseType, masterRoomHouse, roomInfos);

        return CommonResult.success(Boolean.TRUE);
    }

    /**
     * 删除房源
     *
     * @param roomHouseId 房源id
     * @return
     */
    @Override
    public CommonResult<Boolean> delete(@NonNull Long roomHouseId) {
        RoomHouse roomHouse = roomHouseRepository.getById(roomHouseId);
        Assert.isTrue(ObjectUtil.isNotEmpty(roomHouse), "房源信息不存在");
        List<Long> delIds = new ArrayList<>();
        if (roomHouse.getIsWhole()) {
            // 查询当前的房态, 限制只能删除空房,冻结房,维修房
            RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
            Assert.isTrue(roomStateRecord.getState().toString().equals(RentStatusEnum.EMPTY.getValue()) ||
                    roomStateRecord.getState().toString().equals(RentStatusEnum.FREEZE.getValue()) ||
                    roomStateRecord.getState().toString().equals(RentStatusEnum.MAINTENANCE.getValue()), "只能删除空房,冻结房,维修房");
            // 删除房源
            roomHouseRepository.removeById(roomHouseId);
            delIds.add(roomHouseId);
        } else {
            // 合租
            // 如果是主房源, 则查询所有子房间的房态
            if (ObjectUtil.isEmpty(roomHouse.getSuperId())) {
                List<RoomHouse> roomHouses = roomHouseRepository.getBySuperId(roomHouseId).getCheckedData();
                List<Long> ids = roomHouses.stream().map(RoomHouse::getId).collect(Collectors.toList());
                ids.add(roomHouseId);
                List<RoomStateRecord> records = roomStateRecordRepository.getListByRoomIdAndIsCurrentState(ids);
                // 过滤出不可删除的房间
                List<RoomStateRecord> collect = records.stream().filter(roomStateRecord -> {
                    if (roomStateRecord.toString().equals(RentStatusEnum.SCHEDULED.getValue()) ||
                            roomStateRecord.getState().toString().equals(RentStatusEnum.CHECKEDIN.getValue()) ||
                            roomStateRecord.getState().toString().equals(RentStatusEnum.STAYINGIN.getValue())) {
                        return true;
                    } else {
                        return false;
                    }
                }).collect(Collectors.toList());
                Assert.isTrue(ObjectUtil.isEmpty(collect), "存在不可删除的房间");
                // 删除房源
                roomHouseRepository.removeByIds(ids);
                delIds.addAll(ids);
            } else {
                // 查询当前的房态, 限制只能删除空房,冻结房,维修房
                RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
                Assert.isTrue(roomStateRecord == null || roomStateRecord.getState().toString().equals(RentStatusEnum.EMPTY.getValue()) ||
                        roomStateRecord.getState().toString().equals(RentStatusEnum.FREEZE.getValue()) ||
                        roomStateRecord.getState().toString().equals(RentStatusEnum.MAINTENANCE.getValue()), "只能删除空房,冻结房,维修房");
                // 删除房源
                roomHouseRepository.removeById(roomHouseId);
                delIds.add(roomHouseId);
            }
        }
        if (ObjectUtil.isNotEmpty(delIds)) {
            delIds.stream().forEach(p -> roomEsProducer.DeleteRoomEl(p));
        }
        return CommonResult.success(Boolean.TRUE);
    }

    /**
     * 房间冻结
     *
     * @param roomHouseId 房源id
     * @return
     */
    @Override
    public CommonResult<Long> roomFreeze(Long roomHouseId) {
        // 检查房源状态
        RoomHouse roomHouse = roomHouseRepository.myGetById(roomHouseId);
        // 检查当前是不是空房
        RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
        if (!roomStateRecord.getState().equals(RentStatusEnum.EMPTY.getValue())) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "空房才可执行冻结操作");
        }
        // 检查是否锁定
        if (roomHouse.getIsLock()) {
            throw new ServiceException(new ErrorCode(30035, "房间已锁定，不可冻结"));
        }
        // 更新房态到ES
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouseId);
        roomelUpdateReqVO.setHouseState(RentStatusEnum.FREEZE.getValue());
        roomEsProducer.updateRoomEl(roomelUpdateReqVO);
        roomStateRecord.setIsCurrentState(false);
        roomStateRecordRepository.updateById(roomStateRecord);
        return roomStateRecordService.saveRecord(roomHouseId, RentStatusEnum.FREEZE.getValue(), roomStateRecord.getState());
    }

    /**
     * 房间解冻
     *
     * @param roomHouseId
     * @return
     */
    @Override
    public CommonResult<Long> roomUnFreeze(Long roomHouseId) {
        // 检查房源状态
        RoomHouse roomHouse = roomHouseRepository.myGetById(roomHouseId);
        RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
        if (!roomStateRecord.getState().equals(RentStatusEnum.FREEZE.getValue())) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "房间未冻结，已冻结的房间才能解冻");
        }
        // 检查门店是否已经停用
        Apartment apartment = apartmentRepository.myGetById(roomHouse.getApartmentId());
        if (apartment.getIsStop() != null && apartment.getIsStop()) {
            String msg = StrUtil.format("所属门店{}已停用，无法启用", apartment.getName());
            throw new ServiceException(30036, msg);
        }
        // 更新房态到ES
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouseId);
        roomelUpdateReqVO.setHouseState(RentStatusEnum.EMPTY.getValue());
        roomEsProducer.updateRoomEl(roomelUpdateReqVO);
        roomStateRecord.setIsCurrentState(false);
        roomStateRecordRepository.updateById(roomStateRecord);
        return roomStateRecordService.saveRecord(roomHouseId, RentStatusEnum.EMPTY.getValue(), roomStateRecord.getState());
    }

    /**
     * 房源报修
     *
     * @param roomHouseId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> repair(Long roomHouseId) {
        // 检查房源状态
        roomHouseRepository.myGetById(roomHouseId);
        // 房间状态置为报修
        // 检查当前是不是空房
        RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
        if (!roomStateRecord.getState().equals(RentStatusEnum.EMPTY.getValue())) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "空房才可执行维修操作");
        }

        roomStateRecordService.saveRecord(roomHouseId, RentStatusEnum.MAINTENANCE.getValue());
        // 同步房态到es
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouseId);
        roomelUpdateReqVO.setHouseState(RentStatusEnum.MAINTENANCE.getValue());
        roomEsProducer.updateRoomEl(roomelUpdateReqVO);
        return CommonResult.success(Boolean.TRUE);
    }

    @Override
    public CommonResult<Boolean> repairFinish(Long roomHouseId) {
        // 检查房源状态
        roomHouseRepository.myGetById(roomHouseId);
        // 检查当前是不是维修房
        RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
        if (!roomStateRecord.getState().equals(RentStatusEnum.MAINTENANCE.getValue())) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "维修房才可执行启用操作");
        }
        roomStateRecord.setIsCurrentState(false);
        roomStateRecordRepository.updateById(roomStateRecord);
        roomStateRecordService.saveRecord(roomHouseId, RentStatusEnum.EMPTY.getValue(), roomStateRecord.getState());
        // 更新房态到ES
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouseId);
        roomelUpdateReqVO.setHouseState(RentStatusEnum.EMPTY.getValue());
        roomEsProducer.updateRoomEl(roomelUpdateReqVO);
        return CommonResult.success(Boolean.TRUE);
    }

    @Override
    public CommonResult<List<RoomHouseRespVo>> getRoomHouseByIds(List<Long> ids) {
        List<RoomHouseRespVo> roomHouseRespVos = new ArrayList<>();
        for (Long id : ids) {
            RoomHouseRespVo checkedData = getRoomHouseinfoById(id).getCheckedData();
            roomHouseRespVos.add(checkedData);
        }
        return CommonResult.success(roomHouseRespVos);
    }


    @Override
    @Async
    public Boolean houseImport(HouseImportReq req, String key) {
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
        String esKey = "room:house:" + codeUtil.nextCode("ES");
//        try (ExcelReader excelReader = EasyExcel.read("G:\\分散式房源导入模板.xlsx").build()) {
        try (ExcelReader excelReader = EasyExcel.read(oosFileService.oosDownloadFile(req.getFileUrl())).build()) {
            ReadSheet readSheet1 =
                    EasyExcel.readSheet(0).head(WholeLeaseTemplateVo.class).registerReadListener(new WholeLeaseListener(esKey, req.getApartmentId(), req.getTenantId(), req.getUserId(), new AtomicInteger(), this)).build();
            ReadSheet readSheet2 =
                    EasyExcel.readSheet(1).head(PartLeaseTemplateVo.class).registerReadListener(new PartListener(esKey, req.getApartmentId(), req.getTenantId(), req.getUserId(), new AtomicInteger(), this)).build();
            excelReader.read(readSheet1, readSheet2);
        } catch (Exception e) {
            RoomHouseImportResult roomHouseImportResult = new RoomHouseImportResult(3, "导入失败:" + e.getMessage());
            redisTemplate.opsForValue().set(key, JsonUtils.toJsonString(roomHouseImportResult), 1, TimeUnit.HOURS);
            transactionManager.rollback(transactionStatus);
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), e.getMessage());
        }
        RoomHouseImportResult roomHouseImportResult = new RoomHouseImportResult(2, "导入完成！");
        redisTemplate.opsForValue().set(key, JsonUtils.toJsonString(roomHouseImportResult), 1, TimeUnit.HOURS);
        transactionManager.commit(transactionStatus);
        //推送es
        String value = redisTemplate.opsForValue().get(esKey);
        if (StringUtils.isNotEmpty(value)) {
            List<RoomelCreateReqVO> esRooms = JsonUtils.parseArray(value, RoomelCreateReqVO.class);
            if (esRooms != null && esRooms.size() > 0) {
                roomEsProducer.ListAddRoomEl(esRooms);
            }
        }
        return true;
    }

    @Override
    public Boolean batchNoConcentratedAdd(String esKey, List<PartLeaseTemplateVo> list, Long apartmentId, Long tenantId, Long userId, String type) {
        // 校验公寓信息
        Apartment apartment = apartmentRepository.getById(apartmentId);
        Assert.isTrue(ObjectUtil.isNotEmpty(apartment), "公寓信息不存在");
        //房源信息
        List<PartLeaseTemplateVo> rooms = new ArrayList<>();
        if (type.equals("whole")) {
            rooms = list;
        } else if (type.equals("part")) {
            rooms = list.stream().filter(r -> r.getSupperId() == null).collect(Collectors.toList());
        }
        //批量校验新增room_area
        Set<RoomArea> roomAreas = batchAddImportRoomArea(rooms);
        //批量校验新增room_apartment_area
        Set<RoomApartmentArea> roomApartmentAreas = batchAddImportRoomApartmentArea(rooms, apartmentId, tenantId, roomAreas);
        //批量校验新增楼层信息
        Set<RoomFloor> roomFloors = batchAddImportRoomFloor(apartmentId, tenantId, rooms, roomApartmentAreas);
        //批量校验保存户型信息
        Set<RoomHouseType> roomHouseTypes = batchAddImportRoomHouseType(rooms);

        // 保存主，子房源以及相关的备案信息，此时主，子房源的id建立了绑定关系,并且推送备案信息
        batchAddImportRoom(apartment, tenantId, userId, type, rooms, list, roomApartmentAreas, roomFloors, roomHouseTypes);
        //保存房源信息到es上
        batchAddEsImportRoom(esKey, apartment, type, list, roomAreas, roomApartmentAreas, roomFloors, roomHouseTypes);
        //推送备案信息
        pushFillings(tenantId, type, rooms, list);
        return true;
    }

    private Boolean pushFillings(Long tenantId, String type, List<PartLeaseTemplateVo> importRooms, List<PartLeaseTemplateVo> allRooms) {
        for (PartLeaseTemplateVo r : importRooms) {
            // 推送备案信息 - 房源
            InventoryCheckBo bo = new InventoryCheckBo();
            bo.setUniqueDataId(r.getId().toString());
            bo.setSecretKey(filingsProperties.getSecretKey());
            bo.setOwnerName(r.getOwnerName());
            bo.setCardType(CodeTypeEnum.getCodeByName(r.getCardType()));
            bo.setCardNo(r.getCardNo());
            bo.setTelPhone(r.getTelPhone());
            bo.setPropertyNo(r.getPropertyNo());
            bo.setPropertyType(PropertyTypeEnum.getCodeByName(r.getPropertyType()));
            bo.setRegion(r.getDistrict())
                    .setStreetName(r.getStreet())
                    .setItemName(r.getArea())
                    .setBuildNo(r.getBuildingNo() + "栋" + r.getUnitNo() + "单元")
                    .setRoomNo(r.getHouseNo())
                    .setHouseStructure(HouseStructureEnum.getCodeByName(r.getHouseStructure()))
                    .setHouseArea(r.getSpace())
                    // 房源户型 1-一户室，2-二户室，3-三户室，4-四户室，5-四户室以上
                    .setHouseType(r.getRoomNum())
                    .setHouseOrientation(Integer.valueOf(TowardEnum.getValueByName(r.getToward())))
                    .setRenovation(DecorationLevelEnum.getCodeByName(r.getDecoration()))
                    .setRegisterType(HouseTypeEnum.getCodeByName(r.getRegisterType()));
            RoomHouseFilings filings = roomHouseFilingsRepository.getByRoomHouseId(r.getId());
            if (ObjectUtil.isNotEmpty(filings)) {
                bo.setHouseId(filings.getExternalHouseId());
            }
            InventoryRoomCheckBo roomCheckBo = new InventoryRoomCheckBo();
            roomCheckBo.setSecretKey(filingsProperties.getSecretKey());
            roomCheckBo.setOperationType(1);
            roomCheckBo.setUniqueDataId(r.getId().toString());
            roomCheckBo.setRentalMode(2);
            List<InventoryRoomCheckBo.HouseRoom> rooms = new ArrayList<>();
            //获取主房间的子房间
            if (type.equals("part")) {
                List<PartLeaseTemplateVo> chirdRooms = allRooms.stream().filter(c -> c.getSupperId() != null && c.getSupperId().intValue() == r.getId().intValue()).collect(Collectors.toList());
                chirdRooms.stream().forEach(roomInfo -> {
                    InventoryRoomCheckBo.HouseRoom houseRoom = new InventoryRoomCheckBo.HouseRoom().setRoomName(roomInfo.getHouseNo()).setRoomArea(roomInfo.getSpace());
                    RoomHouseFilings roomFilings = roomHouseFilingsRepository.getByRoomHouseId(roomInfo.getId());
                    if (ObjectUtil.isNotEmpty(roomFilings)) {
                        houseRoom.setHouseId(roomFilings.getExternalHouseId());
                    }
                    rooms.add(houseRoom);
                });
                roomCheckBo.setLeaseSubHouseSets(rooms);
            }
            publisher.publishEvent(new InventoryCheckEvent(this, bo, roomCheckBo, tenantId));
        }
        return true;
    }

    private Boolean batchAddEsImportRoom(String esKey, Apartment apartment, String type, List<PartLeaseTemplateVo> list, Set<RoomArea> roomAreas, Set<RoomApartmentArea> roomApartmentAreas, Set<RoomFloor> roomFloors, Set<RoomHouseType> roomHouseTypes) {
        List<RoomelCreateReqVO> esRooms = new ArrayList<>();
        String value = redisTemplate.opsForValue().get(esKey);
        if (StringUtils.isNotEmpty(value)) {
            esRooms = JsonUtils.parseArray(value, RoomelCreateReqVO.class);
        }
        LocalDateTime now = LocalDateTime.now();
//        List<RoomelCreateReqVO> esRooms = list.stream().map(r -> {
        for (PartLeaseTemplateVo r : list) {
            //获取roomArea
            RoomArea roomArea = getRoomAreaFromSetByImport(roomAreas, r);
            //获取roomApartmentAreas
            RoomApartmentArea roomApartmentArea = getRoomApartmentAreaFromSetByImport(roomApartmentAreas, r);
            //获取楼层信息
            RoomFloor roomFloor = getRoomFloorFromSetByImport(roomFloors, apartment.getId(), roomApartmentArea, r);
            RoomHouseType roomHouseType = getRoomHouseTypeFromSetByImport(roomHouseTypes, r);
            RoomelCreateReqVO room = new RoomelCreateReqVO();
            room.setCreateTime(now);
            room.setId(r.getId());
            room.setSuperId(r.getSupperId());
            room.setApartmentAreaId(roomApartmentArea == null ? null : roomApartmentArea.getId());
            room.setApartmentAreaName(roomApartmentArea == null ? null : roomApartmentArea.getArea());
            room.setApartmentName(apartment.getName());
            room.setApartmentId(apartment.getId());
            room.setIsConcentrated(roomApartmentArea == null ? null : roomApartmentArea.getIsConcentrated());
            room.setApartmentAreaLat(roomArea.getGeoLat());
            room.setApartmentAreaLon(roomArea.getGeoLng());
            room.setApartmentLat(apartment.getLatitude());
            room.setApartmentLon(apartment.getLongitude());
            room.setSourceType(apartment.getSourceType());
            room.setFloorId(roomFloor == null ? null : roomFloor.getId());
            room.setBuildingNo(roomApartmentArea == null ? null : roomApartmentArea.getBuildingNo());
            room.setFloorNo(r.getFloor());
            room.setFloorSum(r.getNum());
            room.setCity(roomApartmentArea == null ? null : roomApartmentArea.getCity());
            room.setDistrict(roomApartmentArea == null ? null : roomApartmentArea.getDistrict());
            room.setStreet(roomApartmentArea == null ? null : roomApartmentArea.getStreet());
            room.setAddress(roomApartmentArea == null ? null : roomApartmentArea.getAddress());
            room.setBedroomNum(roomHouseType == null ? null : roomHouseType.getBedRoomNum());
            room.setLivingroomNum(roomHouseType == null ? null : roomHouseType.getLivingRoomNum());
            room.setKitchenNum(roomHouseType == null ? null : roomHouseType.getKitchenNum());
            room.setToiletNum(roomHouseType == null ? null : roomHouseType.getToiletNum());
            room.setRoomHouseTypeId(roomHouseType == null ? null : roomHouseType.getId());
            room.setRoomHouseTypeName(roomHouseType == null ? null : roomHouseType.getName());
            room.setFacetoType(TowardEnum.getValueByName(r.getToward()).toString());
            room.setIsWhole(type.equals("whole"));
            room.setSpace(r.getSpace());
            room.setDecoration(DecorationLevelEnum.getCodeByName(r.getDecoration()).toString());
            room.setHouseState(RentStatusEnum.FREEZE.getValue());
            room.setUnitNo(r.getUnitNo());
            room.setDeptId(apartment.getDeptId());
            room.setTenantId(apartment.getTenantId());
            room.setIsLock(false);
            room.setIsStop(false);
            RoomHouse roomHouse = new RoomHouse();
            BeanUtil.copyProperties(r, roomHouse);
            roomHouse.setName(r.getHouseNo());
            roomHouse.setIsConcentrated(false);
            room.setFullName(RoomHouseUtil.getHouseFullName(roomHouse));
            if (type.equals("whole")) {
                room.setRoomHouseNo(r.getHouseNo());
                room.setRoomHouseName(r.getHouseNo());
            } else if (type.equals("part")) {
                if (r.getRoomType().equals(RoomTypeEnum.GGQY.getName()) || r.getRoomType().equals("主房源")) {
                    room.setRoomHouseNo(r.getNo());
                    room.setRoomHouseName(r.getHouseNo());
                    if (r.getRoomType().equals(RoomTypeEnum.GGQY.getName())) {
                        room.setRoomType(RoomTypeEnum.getValueByName(r.getRoomType()) + "");
                    }
                } else {
                    room.setRoomHouseNo(r.getNo());
                    room.setRoomHouseName(r.getHouseNo() + "-" + r.getNo());
                    room.setRoomType(RoomTypeEnum.getValueByName(r.getRoomType()) + "");
                }
            }
            room.setBalcony(r.getBalcony());

            if (StringUtils.isNotEmpty(r.getRoomType()) && !r.getRoomType().equals("主房源")) {
                room.setRoomType(RoomTypeEnum.getValueByName(r.getRoomType()) + "");
            }
            room.setRoomAreaId(roomApartmentArea.getRoomAreaId());
            esRooms.add(room);
        }
        //存入redis
        if (esRooms != null && esRooms.size() > 0) {
            redisTemplate.opsForValue().set(esKey, JsonUtils.toJsonString(esRooms), 1, TimeUnit.HOURS);
        }
        return true;
    }

    private Boolean batchAddImportRoom(Apartment apartment, Long tenantId, Long userId, String type, List<PartLeaseTemplateVo> rooms, List<PartLeaseTemplateVo> list, Set<RoomApartmentArea> roomApartmentAreas, Set<RoomFloor> roomFloors, Set<RoomHouseType> roomHouseTypes) {
        for (PartLeaseTemplateVo r : rooms) {
//            //获取户型信息
//            RoomHouseType roomHouseType = getRoomHouseTypeFromSetByImport(roomHouseTypes, r);
            //获取小区
//            RoomApartmentArea roomApartmentArea = getRoomApartmentAreaFromSetByImport(roomApartmentAreas, r);
            //如果存在主房源信息就直接报错
            List<RoomHouse> mains = roomHouseRepository.list(
                    new LambdaQueryWrapper<RoomHouse>()
                            .eq(ObjectUtil.isNotEmpty(r.getArea()), RoomHouse::getArea, r.getArea())
                            .eq(RoomHouse::getProvince, "安徽省")
                            .eq(RoomHouse::getCity, "合肥市")
                            .eq(ObjectUtil.isNotEmpty(r.getDistrict()), RoomHouse::getDistrict, r.getDistrict().trim())
                            .eq(ObjectUtil.isNotEmpty(r.getStreet()), RoomHouse::getStreet, r.getStreet().trim())
                            .eq(ObjectUtil.isNotEmpty(r.getAddress()), RoomHouse::getAddress, r.getAddress().trim())
                            .eq(ObjectUtil.isNotEmpty(r.getBuildingNo()), RoomHouse::getBuildingNo, r.getBuildingNo().trim())
                            .eq(ObjectUtil.isNotEmpty(r.getUnitNo()), RoomHouse::getUnitNo, r.getUnitNo().trim())
                            .eq(ObjectUtil.isNotEmpty(r.getHouseNo()), RoomHouse::getHouseNo, r.getHouseNo().trim())
            );


            if (mains != null && mains.size() > 0) {
                throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),
                        r.getArea() + r.getBuildingNo() + "栋" + r.getUnitNo() + "单元" + r.getHouseNo() + "已存在");
            }
        }
        //全量房源添加
        List<RoomHouse> roomHouses = list.stream().map(r -> {
            //获取roomApartmentArea信息
            RoomApartmentArea roomApartmentArea = getRoomApartmentAreaFromSetByImport(roomApartmentAreas, r);
            //获取楼层信息
            RoomFloor roomFloor = getRoomFloorFromSetByImport(roomFloors, apartment.getId(), roomApartmentArea, r);
            RoomHouseType roomHouseType = getRoomHouseTypeFromSetByImport(roomHouseTypes, r);
            RoomHouse roomHouse = new RoomHouse();
            roomHouse.setId(r.getId());
            roomHouse.setNo(codeUtil.nextCode("FJ"));
            roomHouse.setProvince("安徽省");
            roomHouse.setCity("合肥市");
            roomHouse.setDistrict(r.getDistrict().trim());
            roomHouse.setAddress(r.getAddress().trim());
            roomHouse.setArea(r.getArea().trim());
            roomHouse.setStreet(r.getStreet().trim());
            roomHouse.setSpace(r.getSpace());
            roomHouse.setApartmentId(apartment.getId());
            roomHouse.setHouseNo(r.getHouseNo().trim());
            roomHouse.setIsWhole(type.equals("whole"));
            if (type.equals("whole")) {
                roomHouse.setHouseNo(r.getHouseNo().trim());
                roomHouse.setName(r.getHouseNo().trim());
            } else if (type.equals("part")) {
                if (r.getRoomType().equals(RoomTypeEnum.GGQY.getName()) || r.getRoomType().equals("主房源")) {
                    roomHouse.setHouseNo(r.getHouseNo().trim());
                    roomHouse.setName(r.getHouseNo().trim());
                    if (r.getRoomType().equals(RoomTypeEnum.GGQY.getName())) {
                        roomHouse.setRoomType(RoomTypeEnum.getValueByName(r.getRoomType()) + "");
                    }
                } else {
                    roomHouse.setHouseNo(r.getNo());
                    roomHouse.setName(r.getHouseNo() + "-" + r.getNo());
                    roomHouse.setRoomType(RoomTypeEnum.getValueByName(r.getRoomType()) + "");
                }
            }
            roomHouse.setRoomNum(r.getRoomNum());
            roomHouse.setIsStop(false);
            roomHouse.setFloorId(roomFloor == null ? null : roomFloor.getId());
            roomHouse.setFloorNo(r.getFloor().toString());
            roomHouse.setSuperId(r.getSupperId());
            roomHouse.setTenantId(tenantId);
            roomHouse.setDecoration(DecorationLevelEnum.getCodeByName(r.getDecoration()).toString());
            roomHouse.setToward(TowardEnum.getValueByName(r.getToward()));
            roomHouse.setIsConcentrated(false);
            roomHouse.setApartmentAreaId(roomApartmentArea.getId());
            roomHouse.setRoomHouseTypeId(roomHouseType.getId());
            roomHouse.setPeopleNum(r.getPeopleNum());
            roomHouse.setIsLock(false);
            roomHouse.setDeptId(apartment.getDeptId());
            roomHouse.setCreator(String.valueOf(userId));
            roomHouse.setUpdater(String.valueOf(userId));
            //添加buildingNo unitNo
            roomHouse.setBuildingNo(r.getBuildingNo());
            roomHouse.setUnitNo(r.getUnitNo());
            return roomHouse;
        }).collect(Collectors.toList());

        //保存所有房源信息，包括主，子
        roomHouseRepository.saveBatch(roomHouses);

        //保存相对应的产权信息，每个房间都需要生成roomId不同其他都相同的备案信息
        List<RoomHouseInfo> roomHouseInfos = list.stream().map(p -> {
            RoomHouseInfo roomHouseInfo = new RoomHouseInfo();
            roomHouseInfo.setRoomHouseId(p.getId());
            roomHouseInfo.setHouseStructure(HouseStructureEnum.getCodeByName(p.getHouseStructure()).toString());
            roomHouseInfo.setCardNo(p.getCardNo());
            roomHouseInfo.setCardType(CodeTypeEnum.getCodeByName(p.getCardType()).toString());
            roomHouseInfo.setOwnerName(p.getOwnerName());
            roomHouseInfo.setPropertyType(PropertyTypeEnum.getCodeByName(p.getPropertyType()).toString());
            roomHouseInfo.setPropertyNo(p.getPropertyNo());
            roomHouseInfo.setRegisterType(HouseTypeEnum.getCodeByName(p.getRegisterType()).toString());
            roomHouseInfo.setTelPhone(p.getTelPhone());
            roomHouseInfo.setTenantId(tenantId);
            roomHouseInfo.setCreator(String.valueOf(userId));
            roomHouseInfo.setUpdater(String.valueOf(userId));
            return roomHouseInfo;
        }).collect(Collectors.toList());
        //保存备案信息
        roomHouseInfoRepository.saveBatch(roomHouseInfos);

        //插入房态
        List<RoomStateRecord> collect = roomHouses.stream().map(r -> {
            RoomStateRecord roomStateRecord = new RoomStateRecord();
            roomStateRecord.setRoomId(r.getId());
            roomStateRecord.setIsCurrentState(true);
            roomStateRecord.setState(RentStatusEnum.FREEZE.getValue());
            roomStateRecord.setTenantId(tenantId);
            roomStateRecord.setCreator(String.valueOf(userId));
            roomStateRecord.setUpdater(String.valueOf(userId));
            return roomStateRecord;
        }).collect(Collectors.toList());
        roomStateRecordRepository.saveBatch(collect);
        return true;
    }

    private Set<RoomHouseType> batchAddImportRoomHouseType(List<PartLeaseTemplateVo> rooms) {
        Set<RoomHouseType> roomHouseTypeSet = new HashSet<>();
        List<PartLeaseTemplateVo> needAddRoomHouseTypeList = new ArrayList<>();
        List<PartLeaseTemplateVo> roomTypes = new ArrayList<>();
        //房源需要根据户型信息进行分组
        Map<String, List<PartLeaseTemplateVo>> roomHouseTypesMap = rooms.stream().collect(Collectors.groupingBy(p -> fetchRoomHouseTypeKey(p)));
        for (List<PartLeaseTemplateVo> list : roomHouseTypesMap.values()) {
            //每一组里只要取第一个就可以了
            roomTypes.add(list.get(0));
        }
        for (PartLeaseTemplateVo vo : roomTypes) {
            RoomHouseType roomHouseType = roomHouseTypeRepository.getOne(

                    new LambdaQueryWrapper<RoomHouseType>()
                            .eq(ObjectUtil.isNotEmpty(vo.getRoomNum()), RoomHouseType::getBedRoomNum, vo.getRoomNum())
                            .eq(ObjectUtil.isNotEmpty(vo.getLivingRoomNum()), RoomHouseType::getLivingRoomNum, vo.getLivingRoomNum())
                            .eq(ObjectUtil.isNotEmpty(vo.getToiletNum()), RoomHouseType::getToiletNum, vo.getToiletNum())
                            .eq(ObjectUtil.isNotEmpty(vo.getKitchenNum()), RoomHouseType::getKitchenNum, vo.getKitchenNum())
                            .eq(ObjectUtil.isNotEmpty(vo.getBalcony()), RoomHouseType::getBalcony, vo.getBalcony())
            );
            if (ObjectUtil.isEmpty(roomHouseType)) {
                needAddRoomHouseTypeList.add(vo);
            } else {
                roomHouseTypeSet.add(roomHouseType);
            }

        }
        //批量新增新户型
        List<RoomHouseType> roomHouseTypes = needAddRoomHouseTypeList.stream().map(t -> {
            RoomHouseType roomHouseType = new RoomHouseType();
            roomHouseType.setBedRoomNum(t.getRoomNum());
            roomHouseType.setLivingRoomNum(t.getLivingRoomNum());
            roomHouseType.setToiletNum(t.getToiletNum());
            roomHouseType.setKitchenNum(t.getKitchenNum());
            roomHouseType.setBalcony(t.getBalcony());
            StringBuilder name = new StringBuilder();
            if (roomHouseType.getBedRoomNum() != null && roomHouseType.getBedRoomNum() > 0) {
                name.append(roomHouseType.getBedRoomNum());
                name.append("室");
            }
            if (roomHouseType.getLivingRoomNum() != null && roomHouseType.getLivingRoomNum() > 0) {
                name.append(roomHouseType.getLivingRoomNum());
                name.append("厅");
            }
            if (roomHouseType.getKitchenNum() != null && roomHouseType.getKitchenNum() > 0) {
                name.append(roomHouseType.getKitchenNum());
                name.append("厨");
            }
            if (roomHouseType.getToiletNum() != null && roomHouseType.getToiletNum() > 0) {
                name.append(roomHouseType.getToiletNum());
                name.append("卫");
            }
            if (roomHouseType.getBalcony() != null && roomHouseType.getBalcony() > 0) {
                name.append(roomHouseType.getBalcony());
                name.append("阳台");
            }
            roomHouseType.setName(name.toString());
            return roomHouseType;
        }).collect(Collectors.toList());
        roomHouseTypeRepository.saveBatch(roomHouseTypes);
        roomHouseTypeSet.addAll(roomHouseTypes);
        return roomHouseTypeSet;
    }

    private String fetchRoomHouseTypeKey(PartLeaseTemplateVo vo) {
        return vo.getRoomNum() + "_" + vo.getLivingRoomNum() + "_" + vo.getToiletNum() + "_" + vo.getKitchenNum()
                + "_" + vo.getBalcony();
    }

    private Set<RoomFloor> batchAddImportRoomFloor(Long apartmentId, Long tenantId, List<PartLeaseTemplateVo> rooms, Set<RoomApartmentArea> roomApartmentAreas) {
        Set<RoomFloor> roomFloorSet = new HashSet<>();
        List<PartLeaseTemplateVo> needAddRoomFloorList = new ArrayList<>();
        List<PartLeaseTemplateVo> roomFloorList = new ArrayList<>();
        //对RoomFloor进行分组
        //1.填充apartmentId,apartmentAreaId
        rooms = rooms.stream().peek(r -> {
            r.setApartmentId(apartmentId);
            RoomApartmentArea roomApartmentArea = getRoomApartmentAreaFromSetByImport(roomApartmentAreas, r);
            r.setApartmentAreaId(roomApartmentArea.getId());
        }).collect(Collectors.toList());
        //2.对楼层进行分组
        Map<String, List<PartLeaseTemplateVo>> roomFloorMap = rooms.stream().collect(Collectors.groupingBy(p -> fetchRoomFloorKey(p)));
        for (List<PartLeaseTemplateVo> list : roomFloorMap.values()) {
            //每一组里只要取第一个就可以了
            roomFloorList.add(list.get(0));
        }
        for (PartLeaseTemplateVo vo : roomFloorList) {
            //找到相应的roomApartmentArea
            RoomApartmentArea roomApartmentArea = getRoomApartmentAreaFromSetByImport(roomApartmentAreas, vo);
            RoomFloor roomFloor = roomFloorRepository.getOne(
                    new LambdaQueryWrapper<RoomFloor>()
                            .eq(RoomFloor::getApartmentId, apartmentId)
                            .eq(ObjectUtil.isNotEmpty(roomApartmentArea == null ? null : roomApartmentArea.getId()), RoomFloor::getApartmentAreaId, roomApartmentArea == null ? null : roomApartmentArea.getId())
                            .eq(ObjectUtil.isNotEmpty(vo.getFloor()), RoomFloor::getNum, vo.getFloor())
            );
            if (ObjectUtil.isEmpty(roomFloor)) {
                needAddRoomFloorList.add(vo);
            } else {
                roomFloorSet.add(roomFloor);
            }
        }
        //批量新增楼层
        //组装楼层
        List<RoomFloor> roomFloors = needAddRoomFloorList.stream().map(f -> {
            //找到相应的roomApartmentArea
            RoomApartmentArea roomApartmentArea = getRoomApartmentAreaFromSetByImport(roomApartmentAreas, f);
            RoomFloor roomFloor = new RoomFloor();
            roomFloor.setApartmentId(apartmentId);
            roomFloor.setApartmentAreaId(roomApartmentArea == null ? null : roomApartmentArea.getId());
            roomFloor.setFloorRoomNum(1);
            roomFloor.setNum(f.getFloor());
            roomFloor.setName(f.getFloor() + "楼");
            roomFloor.setTenantId(tenantId);
            return roomFloor;
        }).collect(Collectors.toList());
        roomFloorRepository.saveBatch(roomFloors);
        roomFloorSet.addAll(roomFloors);
        return roomFloorSet;
    }

    private String fetchRoomFloorKey(PartLeaseTemplateVo vo) {
        return vo.getApartmentId() + "_" + vo.getApartmentAreaId() + "_" + vo.getFloor();
    }

    private Set<RoomApartmentArea> batchAddImportRoomApartmentArea(List<PartLeaseTemplateVo> rooms, Long apartmentId, Long tenantId, Set<RoomArea> roomAreas) {

        Set<RoomApartmentArea> roomApartmentAreaSet = new HashSet<>();
        //需要新增的公寓下的小区信息存入此集合
        List<PartLeaseTemplateVo> needAddRoomApartmentList = new ArrayList<>();
        //房源需要根据roomApartment信息进行分组
        Map<String, List<PartLeaseTemplateVo>> roomApartmentMap = rooms.stream().collect(Collectors.groupingBy(p -> fetchRoomApartmentKey(p)));
        List<PartLeaseTemplateVo> roomApartmentList = new ArrayList<>();
        for (List<PartLeaseTemplateVo> list : roomApartmentMap.values()) {
            //每一组里只要取第一个就可以了
            roomApartmentList.add(list.get(0));
        }

        roomApartmentList.forEach(vo -> {
            List<RoomApartmentArea> roomApartmentAreas = roomApartmentAreaRepository.list(
                    new LambdaQueryWrapper<RoomApartmentArea>()
                            .eq(RoomApartmentArea::getIsConcentrated, true)
                            .eq(RoomApartmentArea::getArea, vo.getArea())
                            .eq(RoomApartmentArea::getBuildingNo, vo.getBuildingNo())
                            .eq(RoomApartmentArea::getAddress, vo.getAddress())
            );
            if (roomApartmentAreas != null && roomApartmentAreas.size() > 0) {
                throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), vo.getArea() + "集中式已存在");
            }
        });

        for (PartLeaseTemplateVo vo : roomApartmentList) {

            //查询 新增 roomApartmentArea
            List<RoomApartmentArea> roomApartmentAreas = roomApartmentAreaRepository.list(
                    new LambdaQueryWrapper<RoomApartmentArea>()
                            .eq(RoomApartmentArea::getIsConcentrated, false)
                            .eq(RoomApartmentArea::getApartmentId, apartmentId)
                            .eq(RoomApartmentArea::getUnitNo, vo.getUnitNo())
                            .eq(ObjectUtil.isNotEmpty(vo.getAddress()), RoomApartmentArea::getAddress, vo.getAddress())
                            .eq(ObjectUtil.isNotEmpty(vo.getArea()), RoomApartmentArea::getArea, vo.getArea())
                            .eq(ObjectUtil.isNotEmpty(vo.getBuildingNo()), RoomApartmentArea::getBuildingNo, vo.getBuildingNo())
                            .eq(ObjectUtil.isNotEmpty(vo.getUnitNo()), RoomApartmentArea::getUnitNo, vo.getUnitNo())
                            .eq(RoomApartmentArea::getProvince, "安徽省")
                            .eq(RoomApartmentArea::getCity, "合肥市")
                            .eq(RoomApartmentArea::getDistrict, vo.getDistrict())
                            .eq(RoomApartmentArea::getStreet, vo.getStreet())
            );
            if (roomApartmentAreas != null && roomApartmentAreas.size() > 0) {
                roomApartmentAreaSet.add(roomApartmentAreas.get(0));
            } else {
                needAddRoomApartmentList.add(vo);
            }
        }
        //批量新增小区信息
        List<RoomApartmentArea> roomApartmentAreas = needAddRoomApartmentList.stream().map(r -> {
            RoomApartmentArea roomApartmentArea = new RoomApartmentArea();
            // 保存公寓小区信息
            roomApartmentArea.setApartmentId(apartmentId);
            //找到roomArea信息
            RoomArea roomArea = getRoomAreaFromSetByImport(roomAreas, r);
            roomApartmentArea.setRoomAreaId(roomArea == null ? null : roomArea.getId());
            roomApartmentArea.setIsConcentrated(false);
            roomApartmentArea.setBuildingNo(r.getBuildingNo());
            roomApartmentArea.setUnitNo(r.getUnitNo());
            roomApartmentArea.setArea(r.getArea());
            roomApartmentArea.setProvince("安徽省");
            roomApartmentArea.setCity("合肥市");
            roomApartmentArea.setDistrict(r.getDistrict());
            roomApartmentArea.setStreet(r.getStreet());
            roomApartmentArea.setAddress(r.getAddress());
            roomApartmentArea.setFloorNum(r.getNum());
            roomApartmentArea.setGroundFloorNum(r.getFloor());
            roomApartmentArea.setFloorRoomNum(0);
            roomApartmentArea.setRoomNum(1);
            roomApartmentArea.setTenantId(tenantId);
            return roomApartmentArea;
        }).collect(Collectors.toList());
        roomApartmentAreaRepository.saveBatch(roomApartmentAreas);
        roomApartmentAreaSet.addAll(roomApartmentAreas);
        return roomApartmentAreaSet;
    }

    private String fetchRoomApartmentKey(PartLeaseTemplateVo vo) {
        return vo.getAddress() + "_" + vo.getArea() + "_" + vo.getBuildingNo() + "_" + vo.getUnitNo();
    }

    private RoomHouseType getRoomHouseTypeFromSetByImport(Set<RoomHouseType> roomHouseTypes, PartLeaseTemplateVo vo) {
        RoomHouseType roomHouseType = null;
        Optional<RoomHouseType> roomHouseTypeInfo = roomHouseTypes.stream().filter(t -> t.getBedRoomNum().intValue() == vo.getRoomNum().intValue()
                && t.getLivingRoomNum().intValue() == vo.getLivingRoomNum().intValue()
                && t.getKitchenNum().intValue() == vo.getKitchenNum().intValue()
                && t.getToiletNum().intValue() == vo.getToiletNum().intValue()
                && t.getBalcony().intValue() == vo.getBalcony().intValue()).findFirst();
        if (roomHouseTypeInfo.isPresent()) {
            roomHouseType = roomHouseTypeInfo.get();
        }
        return roomHouseType;
    }

    private RoomFloor getRoomFloorFromSetByImport(Set<RoomFloor> roomFloors, Long apartmentId, RoomApartmentArea roomApartmentArea, PartLeaseTemplateVo vo) {
        RoomFloor roomFloor = null;
        Optional<RoomFloor> roomFloorInfo = roomFloors.stream().filter(f -> f.getApartmentId().intValue() == apartmentId.intValue()
                && f.getApartmentAreaId().intValue() == roomApartmentArea.getId().intValue()
                && f.getNum().intValue() == vo.getFloor().intValue()).findFirst();
        if (roomFloorInfo.isPresent()) {
            roomFloor = roomFloorInfo.get();
        }
        return roomFloor;
    }

    private RoomApartmentArea getRoomApartmentAreaFromSetByImport(Set<RoomApartmentArea> roomApartmentAreas, PartLeaseTemplateVo vo) {
        RoomApartmentArea roomApartmentArea = null;
        Optional<RoomApartmentArea> roomApartmentAreaInfo = roomApartmentAreas.stream().filter(a -> a.getAddress().equals(vo.getAddress())
                && a.getArea().equals(vo.getArea())
                && a.getBuildingNo().equals(vo.getBuildingNo())).findFirst();
        if (roomApartmentAreaInfo.isPresent()) {
            roomApartmentArea = roomApartmentAreaInfo.get();
        }
        return roomApartmentArea;
    }

    private RoomArea getRoomAreaFromSetByImport(Set<RoomArea> roomAreas, PartLeaseTemplateVo vo) {
        RoomArea roomArea = null;
        Optional<RoomArea> roomAreaInfo = roomAreas.stream().filter(a -> a.getAddress().equals(vo.getAddress())
                && a.getDistrict().equals(vo.getDistrict())
                && a.getName().equals(vo.getArea())).findFirst();
        if (roomAreaInfo.isPresent()) {
            roomArea = roomAreaInfo.get();
        }
        return roomArea;
    }

    private Set<RoomArea> batchAddImportRoomArea(List<PartLeaseTemplateVo> rooms) {
        Set<RoomArea> roomAreaSet = new HashSet<>();
        //需要新增的小区信息存入此集合
        List<PartLeaseTemplateVo> needAddRoomAreaList = new ArrayList<>();
        //房源需要根据roomAreas进行分组
        Map<String, List<PartLeaseTemplateVo>> roomAreasMap = rooms.stream().collect(Collectors.groupingBy(p -> fetchroomAreaKey(p)));
        List<PartLeaseTemplateVo> roomAreaList = new ArrayList<>();
        for (List<PartLeaseTemplateVo> list : roomAreasMap.values()) {
            //每一组里只要取第一个就可以了
            roomAreaList.add(list.get(0));
        }
        for (PartLeaseTemplateVo vo : roomAreaList) {
            RoomArea roomArea = roomAreaRepository.getOne(new LambdaQueryWrapper<RoomArea>()
                    .eq(ObjectUtil.isNotEmpty(vo.getDistrict()), RoomArea::getDistrict, vo.getDistrict())
                    .eq(ObjectUtil.isNotEmpty(vo.getArea()), RoomArea::getName, vo.getArea())
                    .eq(ObjectUtil.isNotEmpty(vo.getAddress()), RoomArea::getAddress, vo.getAddress())
            );
            if (ObjectUtil.isEmpty(roomArea)) {
                needAddRoomAreaList.add(vo);
            } else {
                roomAreaSet.add(roomArea);
            }
        }

        List<RoomArea> roomAreas = needAddRoomAreaList.stream().map(r -> {
            RoomArea roomArea = new RoomArea();
            roomArea.setName(r.getArea());
            Pinyin4jEngine engine = new Pinyin4jEngine();
            roomArea.setEname(engine.getPinyin(r.getAddress(), ""));
            roomArea.setProvince("安徽省");
            roomArea.setCity("合肥市");
            roomArea.setDistrict(r.getDistrict());
            roomArea.setStreet(r.getStreet());
            roomArea.setAddress(r.getAddress());
            // 获取经纬度
            String location = " , ";
            String province = ObjectUtil.isNotEmpty(roomArea.getProvince()) ? roomArea.getProvince() : "";
            String city = ObjectUtil.isNotEmpty(roomArea.getCity()) ? roomArea.getCity() : "";
            String district = ObjectUtil.isNotEmpty(roomArea.getDistrict()) ? roomArea.getDistrict() : "";
            String street = ObjectUtil.isNotEmpty(roomArea.getStreet()) ? roomArea.getStreet() : "";
            String areaName = ObjectUtil.isNotEmpty(roomArea.getName()) ? roomArea.getName() : "";
            String address = ObjectUtil.isNotEmpty(roomArea.getAddress()) ? roomArea.getAddress() : "";
            String realAddress = province + city + district + street + areaName + address;
            try {
                location = baiDuMapUtil.locationSearch(realAddress,city);
            } catch (Exception e) {
                log.info(e.getMessage());
                log.info("小区地址:{} 解析经纬度失败!", realAddress);
            }
            String[] split = location.split(",");
            roomArea.setGeoLng(split[0]);
            roomArea.setGeoLat(split[1]);
            return roomArea;
        }).collect(Collectors.toList());
        //批量新增room_area
        roomAreaRepository.saveBatch(roomAreas);
        //把roomAreas加入set里
        roomAreaSet.addAll(roomAreas);
        return roomAreaSet;
    }

    private String fetchroomAreaKey(PartLeaseTemplateVo vo) {
        return vo.getDistrict() + "_" + vo.getArea() + "_" + vo.getAddress();
    }

    @Override
    public CommonResult<RoomHouseRespVo> getRoomHouseinfoById(Long roomHouseId) {

        RoomHouse roomHouse = roomHouseRepository.myGetById(roomHouseId);
        RoomHouseRespVo respVo = RoomHouseConvert.INSTANCE.convert(roomHouse);
        RoomFloor roomFloor = roomFloorRepository.myGetById(roomHouse.getFloorId());
        Apartment apartment = apartmentRepository.myGetById(roomHouse.getApartmentId());
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.myGetById(roomHouse.getApartmentAreaId());
        RoomHouseType roomHouseType = roomHouseTypeRepository.myGetById(roomHouse.getRoomHouseTypeId());
        RoomHouseInfo roomHouseInfo = roomHouseInfoRepository.getByRoomHouseId(roomHouseId);

        StringBuilder sb = new StringBuilder();
        sb.append(roomHouse.getArea());
        sb.append(roomHouse.getBuildingNo());
        sb.append("栋");
        if (!roomHouse.getIsConcentrated()) {
            sb.append(roomHouse.getUnitNo());
            sb.append("单元");
        }
        sb.append(roomHouse.getName());
        String fullName = sb.toString();

        respVo.setFloorName(roomFloor.getName());
        respVo.setFullRoomName(fullName);
        respVo.setBedRoomNum(roomHouseType.getBedRoomNum());
        respVo.setLivingRoomNum(roomHouseType.getLivingRoomNum());
        respVo.setToiletNum(roomHouseType.getToiletNum());
        respVo.setKitchenNum(roomHouseType.getKitchenNum());
        respVo.setBalcony(roomHouseType.getBalcony());
        respVo.setApartmentName(apartment.getName());
        respVo.setBuildingNo(roomApartmentArea.getBuildingNo());
        respVo.setUnitNo(roomApartmentArea.getUnitNo());
        respVo.setRoomHouseTypeName(roomHouseType.getName());
        respVo.setTotalFloorNum(roomApartmentArea.getFloorNum());
        respVo.setGroundFloorNum(roomApartmentArea.getGroundFloorNum());
        respVo.setPropertyNo(roomHouseInfo.getPropertyNo());
        respVo.setOwnerName(roomHouseInfo.getOwnerName());
        respVo.setDeptId(roomHouse.getDeptId());
        return CommonResult.success(respVo);
    }

    @Override
    public CommonResult<RoomHouseRespVo> queryByHouseAddr(String roomHouseAddr, Long apartmentId) {
        //南虹公寓1栋109
        LambdaQueryWrapper<RoomHouse> wrapper = Wrappers.lambdaQuery();
        String[] split = roomHouseAddr.split("-");
        for (String item : split) {
            if(item.contains("栋")){
                wrapper.eq(RoomHouse::getBuildingNo, item.replace("栋",""));
            }else if(item.contains("单元")){
                wrapper.eq(RoomHouse::getUnitNo, item.replace("栋",""));
            }else if(NumberUtil.isNumber(item)){
                wrapper.eq(RoomHouse::getHouseNo, item.replace("栋",""));
            }else {
                wrapper.eq(RoomHouse::getArea, item);
            }
        }
        wrapper.eq(RoomHouse::getApartmentId, apartmentId);
        wrapper.eq(RoomHouse::getDeleted, 0);
        RoomHouse roomHouse = roomHouseRepository.queryByWrapper(wrapper);
        RoomHouseRespVo respVo = RoomHouseConvert.INSTANCE.convert(roomHouse);
        return CommonResult.success(respVo);
    }

    /**
     * 所有小区/楼栋名称的树形结构
     *
     * @param isConcentrated
     * @return
     */
    @Override
    public CommonResult<List<GetRoomHouseTreeRespVO>> getRoomHouseTree(Boolean isConcentrated) {
        // 查询所有房源
        List<GetRoomHouseTreeRespVO> respVOS = new ArrayList<>();
        List<RoomHouse> roomHouses = roomHouseRepository.getByIsConcentratedGroupByAddress(isConcentrated);
        roomHouses.forEach(roomHouse -> {
            GetRoomHouseTreeRespVO respVO = new GetRoomHouseTreeRespVO();
            respVO.setName(roomHouse.getArea());
            List<RoomApartmentArea> slaveRoomApartmentAreas = roomApartmentAreaRepository.getByAddressAndIsConcentrate(roomHouse);
            List<SlaveRoomHouseVO> slaveRoomHouseVOS = new ArrayList<>();
            slaveRoomApartmentAreas.forEach(slaveRoomApartmentArea -> {
                SlaveRoomHouseVO slaveRoomHouseVO = new SlaveRoomHouseVO();
                StringBuilder sb = new StringBuilder(slaveRoomApartmentArea.getBuildingNo());
                sb.append("栋");
                if (ObjectUtil.isNotEmpty(slaveRoomApartmentArea.getUnitNo())) {
                    sb.append(slaveRoomApartmentArea.getUnitNo());
                    sb.append("单元");
                }
                slaveRoomHouseVO.setName(sb.toString());
                slaveRoomHouseVO.setApartmentAreaId(slaveRoomApartmentArea.getId());
                slaveRoomHouseVOS.add(slaveRoomHouseVO);
            });
            respVO.setSlaveRoomHouseVos(slaveRoomHouseVOS);
            respVOS.add(respVO);
        });
        return CommonResult.success(respVOS);
    }

    /**
     * 获取所有房源列表
     *
     * @param tenantId                 租户id
     * @param apartmentId              门店id
     * @param isConcentrated           是否集中式
     * @param houseState               房态 RentStatusEnum.value
     * @param isLock
     * @param onlyShowPrimaryRoomHouse 是否只显示主房源
     * @return
     */
    @Override
    public CommonResult<List<AllRoomHouseRespVO>> allRoomHouse(Long tenantId, Long apartmentId, Boolean isConcentrated, String houseState, Boolean isLock, Boolean onlyShowPrimaryRoomHouse) {
        SearchRequest searchRequest = new SearchRequest(ApiConstants.ROOMELENTIRY);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 查询条件， 查询当前租户
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery(IsStop, false))
                .must(QueryBuilders.termQuery(TenantId, tenantId));
        if (ObjectUtil.isNotEmpty(apartmentId)) {
            boolQueryBuilder.must(QueryBuilders.termQuery(ApartmentId, apartmentId));
        }

        if (onlyShowPrimaryRoomHouse) {
            // 需要只展示主房源的话, 查询集中式 和 分散式没有superId的房源
            BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
            queryBuilder.should(QueryBuilders.termQuery(IsConcentrated, true));
            BoolQueryBuilder boolQueryBuilder2 = new BoolQueryBuilder();

            BoolQueryBuilder boolQueryBuilder3 = new BoolQueryBuilder();
            boolQueryBuilder3.must(QueryBuilders.termQuery(IsConcentrated, false));
            boolQueryBuilder3.mustNot(QueryBuilders.existsQuery(SuperId));
            boolQueryBuilder2.must(boolQueryBuilder3);

            queryBuilder.should(boolQueryBuilder2);
            boolQueryBuilder.must(queryBuilder);
        } else {
            if (ObjectUtil.isNotEmpty(isConcentrated) && isConcentrated) {
                QueryBuilder queryBuilder10 = QueryBuilders.termQuery(IsConcentrated, true);
                boolQueryBuilder.must(queryBuilder10);
            } else if (ObjectUtil.isNotEmpty(isConcentrated) && !isConcentrated) {
                QueryBuilder queryBuilder10 = QueryBuilders.termQuery(IsConcentrated, false);
                boolQueryBuilder.must(queryBuilder10);
                // 分散式只查询整租 or 合租的子房间
                BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
                queryBuilder.should(QueryBuilders.termQuery(IsWhole, true));
                BoolQueryBuilder boolQueryBuilder2 = new BoolQueryBuilder();

                BoolQueryBuilder boolQueryBuilder3 = new BoolQueryBuilder();
                boolQueryBuilder3.must(QueryBuilders.termQuery(IsWhole, false));
                boolQueryBuilder3.must(QueryBuilders.existsQuery(SuperId));
                boolQueryBuilder2.must(boolQueryBuilder3);

                BoolQueryBuilder boolQueryBuilder5 = new BoolQueryBuilder();
                boolQueryBuilder5.mustNot(QueryBuilders.termQuery(RoomType + ".keyword", RoomTypeEnum.GGQY.getValue()));
                boolQueryBuilder2.must(boolQueryBuilder5);
                queryBuilder.should(boolQueryBuilder2);

                boolQueryBuilder.must(queryBuilder);
            } else if (ObjectUtil.isEmpty(isConcentrated)) {
                // 查询整租 or 合租的子房间
                BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
                queryBuilder.should(QueryBuilders.termQuery(IsWhole, true));
                BoolQueryBuilder boolQueryBuilder2 = new BoolQueryBuilder();

                BoolQueryBuilder boolQueryBuilder3 = new BoolQueryBuilder();
                boolQueryBuilder3.must(QueryBuilders.termQuery(IsWhole, false));
                boolQueryBuilder3.must(QueryBuilders.existsQuery(SuperId));
                boolQueryBuilder2.must(boolQueryBuilder3);

                BoolQueryBuilder boolQueryBuilder5 = new BoolQueryBuilder();
                boolQueryBuilder5.mustNot(QueryBuilders.termQuery(RoomType + ".keyword", RoomTypeEnum.GGQY.getValue()));
                boolQueryBuilder2.must(boolQueryBuilder5);
                queryBuilder.should(boolQueryBuilder2);

                boolQueryBuilder.must(queryBuilder);
            }
        }


        if (ObjectUtil.isNotEmpty(houseState)) {
            boolQueryBuilder.must(QueryBuilders.termQuery(HouseState, houseState));
        }
        if (ObjectUtil.isNotEmpty(isLock)) {
            boolQueryBuilder.must(QueryBuilders.termQuery(IsLock, isLock));
        }
        // 按照小区分组
        TermsAggregationBuilder areaGroup = AggregationBuilders.terms("areaGroup").field(ApartmentAreaId).size(MAX_GROUP_SIZE);
        // 按楼栋分组
        TermsAggregationBuilder buildingGroup = AggregationBuilders.terms("buildingGroup").field(BuildingNo + ".keyword").size(MAX_GROUP_SIZE);
        // 按单元分组
        TermsAggregationBuilder unitGroup = AggregationBuilders.terms("unitGroup").field(UnitNo + ".keyword").size(MAX_GROUP_SIZE);
        // 按楼层分组
        TermsAggregationBuilder floorGroup = AggregationBuilders.terms("floorGroup").field(FloorNo).size(MAX_GROUP_SIZE);
        // 获取小区房源信息
        TopHitsAggregationBuilder areaInfoTopHits = AggregationBuilders.topHits("areaInfo")
                .fetchSource(new String[]{Id, ApartmentAreaName, BuildingNo, UnitNo, RoomHouseName, FullName, City, District, Street, Address}, null).size(100);
        // 获取楼层的房间信息
        floorGroup.subAggregation(areaInfoTopHits);
        // 将楼层作为单元的子分组条件
        unitGroup.subAggregation(floorGroup);
        // 将单元作为楼栋的子分组条件
        buildingGroup.subAggregation(unitGroup);
        // 获取小区信息
        TopHitsAggregationBuilder areaTopHits = AggregationBuilders.topHits("area")
                .fetchSource(new String[]{ApartmentAreaName, IsConcentrated}, null)
                .size(1);
        // 按小区分组后获取小区的信息
        areaGroup.subAggregation(areaTopHits);
        // 将楼栋作为小区的子分组条件
        areaGroup.subAggregation(buildingGroup);
        // 设置查询条件
        searchSourceBuilder.query(boolQueryBuilder);
        // 设置分组条件
        searchSourceBuilder.aggregation(areaGroup);
        // 构建查询请求
        searchRequest.source(searchSourceBuilder);
        // 初始化接口响应对象
        List<AllRoomHouseRespVO> allRoomHouseRespVOS = new ArrayList<>();
        try {
            // 发起查询
            SearchResponse searchResponse = elasticsearchTemplate.search(searchRequest);
            // 解析查询结果
            ParsedTerms parsedTerms = (ParsedTerms) searchResponse.getAggregations().asMap().get("areaGroup");
            List<? extends Terms.Bucket> buckets = parsedTerms.getBuckets();
            AtomicReference<String> name = new AtomicReference<>("");
            buckets.stream().forEach(bucket -> {
                ParsedTerms buildingTerms = (ParsedTerms) bucket.getAggregations().asMap().get("buildingGroup");
                // 小区id
                AllRoomHouseNameVO roomHouseNameVO = new AllRoomHouseNameVO();
                ParsedTopHits areatophits = (ParsedTopHits) bucket.getAggregations().asMap().get("area");
                SearchHit[] areaHits = areatophits.getHits().getHits();
                for (SearchHit areaHit : areaHits) {
                    Map<String, Object> sourceAsMap = areaHit.getSourceAsMap();
                    String apartmentAreaName = sourceAsMap.get(ApartmentAreaName).toString();
                    Boolean roomIsConcentrated = (Boolean) sourceAsMap.get(IsConcentrated);
                    roomHouseNameVO.setApartmentAreaName(apartmentAreaName);
                    roomHouseNameVO.setIsConcentrated(roomIsConcentrated);
                }
                List<? extends Terms.Bucket> buildingTermBuckets = buildingTerms.getBuckets();
                buildingTermBuckets.stream().forEach(buildingTermBucket -> {
                    // 楼栋
                    String building = buildingTermBucket.getKeyAsString();
                    roomHouseNameVO.setBuilding(building);
                    ParsedTerms unitTerms = (ParsedTerms) buildingTermBucket.getAggregations().asMap().get("unitGroup");
                    List<? extends Terms.Bucket> unitTermsBuckets = unitTerms.getBuckets();
                    unitTermsBuckets.stream().forEach(unitTermsBucket -> {
                        // 单元
                        String unit = unitTermsBucket.getKeyAsString();
                        roomHouseNameVO.setUnit(unit);
                        AllRoomHouseRespVO allRoomHouseRespVO = new AllRoomHouseRespVO();
                        allRoomHouseRespVO.setName(roomHouseNameVO.toString());
                        ParsedTerms floorTerms = (ParsedTerms) unitTermsBucket.getAggregations().asMap().get("floorGroup");
                        List<? extends Terms.Bucket> floorTermsBuckets = floorTerms.getBuckets();
                        List<AllRoomHouseFloorVO> allRoomHouseFloorVOS = new ArrayList<>();
                        floorTermsBuckets.stream().forEach(floorTermsBucket -> {
                            // 楼层
                            String floor = floorTermsBucket.getKeyAsString();
                            AllRoomHouseFloorVO allRoomHouseFloorVO = new AllRoomHouseFloorVO();
                            allRoomHouseFloorVO.setName(floor + "层");
                            ParsedTopHits areaInfoHits = (ParsedTopHits) floorTermsBucket.getAggregations().asMap().get("areaInfo");
                            SearchHit[] hits = areaInfoHits.getHits().getHits();
                            List<AllRoomHouseVO> allRoomHouseVOS = new ArrayList<>();
                            for (SearchHit hit : hits) {
                                // 房间信息
                                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                                RoomelEntity roomel = JsonUtils.parseObject(hit.getSourceAsString(), RoomelEntity.class);
                                AllRoomHouseVO allRoomHouseVO = new AllRoomHouseVO();
                                allRoomHouseVO.setRoomHouseId(roomel.getId().toString());
                                allRoomHouseVO.setRoomHouseName(roomel.getRoomHouseName());
                                allRoomHouseVO.setRoomFullName(ObjectUtil.isEmpty(roomel.getFullName()) ? null : roomel.getFullName());
                                allRoomHouseVO.setAddress(roomel.getCity() + roomel.getDistrict() + roomel.getStreet() + roomel.getAddress() + roomel.getApartmentAreaName());
                                allRoomHouseVOS.add(allRoomHouseVO);
                            }
                            allRoomHouseFloorVO.setAllRoomHouseVOS(allRoomHouseVOS);
                            allRoomHouseFloorVOS.add(allRoomHouseFloorVO);
                        });
                        allRoomHouseRespVO.setAllRoomHouseFloorVOS(allRoomHouseFloorVOS);
                        allRoomHouseRespVOS.add(allRoomHouseRespVO);
                    });
                });
            });
        } catch (Exception e) {
            log.error(Marker.ANY_MARKER, e);
            throw new RuntimeException(e);
        }
        return CommonResult.success(allRoomHouseRespVOS);
    }


    /**
     * 根据小区和楼栋回显房源信息
     *
     * @param province   小区所在省
     * @param city       小区所在市
     * @param district   区
     * @param street     街道
     * @param areaName   小区名
     * @param buildingNo 楼栋号
     * @return
     */
    @Override
    public CommonResult<ConcentratedAddVO> getRoomHouseInfoByAreaBuilding(String province, String city, String district, String street, String address, String areaName, String buildingNo) {
        // 根据areaId 和 楼栋 确定apartmentArea
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.getByAddressAndBuilding(province, city, district, street, address, areaName, buildingNo, null);
        if (ObjectUtil.isEmpty(roomApartmentArea)) {
            return CommonResult.success(null);
        }
        ConcentratedAddVO concentratedAddVO = new ConcentratedAddVO();

        // 楼层数
        concentratedAddVO.setFloorNum(roomApartmentArea.getFloorNum());
        // 地上楼层数
        concentratedAddVO.setGroundFloorNum(roomApartmentArea.getGroundFloorNum());
        // 每层房间数
        concentratedAddVO.setFloorRoomNum(roomApartmentArea.getFloorRoomNum());
        // 楼层信息
        List<RoomFloor> roomFloors = roomFloorRepository.getByApartmentAreaId(roomApartmentArea.getId());
        List<Integer> inFloorNums = roomFloors.stream().map(RoomFloor::getNum).collect(Collectors.toList());
        // 所在楼层
        concentratedAddVO.setInFloorNum(inFloorNums);
        // 每层的房间信息
        Map<Integer, List<RoomInfoDto>> roomInfo = new HashMap<>();
        for (RoomFloor roomFloor : roomFloors) {
            List<RoomHouse> roomHouses = roomHouseRepository.getByApartmentAreaIdAndFloorId(roomApartmentArea.getId(), roomFloor.getId());
            List<RoomInfoDto> roomInfoDtos = new ArrayList<>();
            roomHouses.forEach(roomHouse -> {
                RoomInfoDto roomInfoDto = new RoomInfoDto();
                roomInfoDto.setLayoutId(roomHouse.getLayoutId());
                roomInfoDto.setName(roomHouse.getName());
                roomInfoDto.setToward(roomHouse.getToward());
                roomInfoDtos.add(roomInfoDto);
            });
            roomInfo.put(roomFloor.getNum(), roomInfoDtos);
        }
        concentratedAddVO.setRoomInfo(roomInfo);
        return CommonResult.success(concentratedAddVO);
    }

    /**
     * 分散式-根据小区信息和楼栋单元回显房源信息
     *
     * @param province
     * @param city
     * @param district
     * @param street
     * @param address
     * @param areaName
     * @param buildingNo
     * @param unitNo
     * @return
     */
    @Override
    public CommonResult<NoConcentratedEchoRespVO> getNoConcentrateRoomHouseInfoByAreaBuilding(String province, String city, String district, String street, String address, String areaName, String buildingNo, String unitNo) {
        // 根据areaId 和 楼栋 确定apartmentArea
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.getByAddressAndBuilding(province, city, district, street, address, areaName, buildingNo, unitNo);
        if (ObjectUtil.isEmpty(roomApartmentArea)) {
            return CommonResult.success(null);
        }
        NoConcentratedEchoRespVO noConcentratedEchoRespVO = new NoConcentratedEchoRespVO();
        noConcentratedEchoRespVO.setFloorNum(roomApartmentArea.getFloorNum());
        noConcentratedEchoRespVO.setGroundFloorNum(roomApartmentArea.getGroundFloorNum());
        return CommonResult.success(noConcentratedEchoRespVO);
    }

    /**
     * 冻结部门下所有房间
     *
     * @param deptId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> roomFreezeByDeptId(Long deptId) {
        List<Apartment> apartments = apartmentRepository.getByDeptId(deptId);
        for (Apartment apartment : apartments) {
            // 将门店置为已停用
            apartment.setIsStop(true);
            apartmentRepository.updateById(apartment);
            List<RoomHouse> roomHouses = roomHouseRepository.getByApartmentId(apartment.getId());
            for (RoomHouse roomHouse : roomHouses) {
                try {
                    this.roomFreeze(roomHouse.getId());
                } catch (Exception e) {
                    throw new ServiceException(new ErrorCode(30038, "该门店已有业务，不予关闭"));
                }
            }
        }
        return CommonResult.success(Boolean.TRUE);
    }

    /**
     * 解冻部门下的所有房源
     *
     * @param deptId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> roomUnFreezeByDeptId(Long deptId) {
        List<Apartment> apartments = apartmentRepository.getByDeptId(deptId);
        for (Apartment apartment : apartments) {
            apartment.setIsStop(false);
            apartmentRepository.updateById(apartment);
            List<RoomHouse> roomHouses = roomHouseRepository.getByApartmentId(apartment.getId());
            for (RoomHouse roomHouse : roomHouses) {
                this.roomUnFreeze(roomHouse.getId());
            }
        }
        return CommonResult.success(Boolean.TRUE);
    }

    /**
     * 根据房源id获取对应门店信息
     *
     * @param roomHouseId
     * @return
     */
    @Override
    public CommonResult<ApartmentVO> getApartmentInfoByRoomHouse(Long roomHouseId) {
        RoomHouse roomHouse = roomHouseRepository.myGetById(roomHouseId);
        Apartment apartment = apartmentRepository.myGetById(roomHouse.getApartmentId());
        ApartmentVO apartmentVO = ApartmentConvert.INSTANCE.convert(apartment);
        //获取测算最高价格
        RoomHouseEstimate roomHouseEstimate=roomHouseEstimateRepository.getEstimateByRoomId(roomHouseId);
        if(!ObjectUtils.isEmpty(roomHouseEstimate)){
            apartmentVO.setHighestPrice(roomHouseEstimate.getHighestPrice());
        }
        return CommonResult.success(apartmentVO);
    }

    /**
     * 根据租客的手机号查询对应的房源信息
     * @param tenantId 租户ID
     * @param phone 租客手机号
     * @return
     */
    @Override
    public CommonResult<GetRoomHouseByTenantPhoneRespVO> getRoomHouseByTenantPhone(Long tenantId, String phone) {
        // 查询该租客所有的房源
        List<RoomelEntity> roomelEntityList = roomelEntityRepository.getRoomHouseByTenantPhone(tenantId, phone);
        if(ObjectUtil.isEmpty(roomelEntityList)){
            return CommonResult.success();
        }
        // 过滤出所有门店ID
        Set<Long> apartmentIds = roomelEntityList.stream().map(RoomelEntity::getApartmentId).collect(Collectors.toSet());
        List<Apartment> apartments = apartmentRepository.listByIds(apartmentIds);

        // 按照小区名,楼栋,单元分组
        Map<String, List<RoomelEntity>> listMap = roomelEntityList.stream().collect(Collectors.groupingBy(roomelEntity -> {
            String unit = !roomelEntity.getIsConcentrated() ? roomelEntity.getUnitNo() + "单元" : "";
            return roomelEntity.getApartmentAreaName() + roomelEntity.getBuildingNo() + "栋" + unit;
        }));
        List<AllRoomHouseRespVO> allRoomHouseRespVOS = new ArrayList<>();
        listMap.entrySet().forEach(p -> {
            AllRoomHouseRespVO allRoomHouseRespVO = new AllRoomHouseRespVO();
            String name = p.getKey();
            allRoomHouseRespVO.setName(name);
            Long apartmentId = p.getValue().get(0).getApartmentId();
            String apartmentName = p.getValue().get(0).getApartmentName();
            allRoomHouseRespVO.setApartmentId(apartmentId);
            allRoomHouseRespVO.setApartmentName(apartmentName);
            Map<Integer, List<RoomelEntity>> collect = p.getValue().stream().collect(Collectors.groupingBy(RoomelEntity::getFloorNo));
            List<AllRoomHouseFloorVO> allRoomHouseFloorVOS = new ArrayList<>();
            collect.entrySet().forEach(s -> {
                AllRoomHouseFloorVO allRoomHouseFloorVO = new AllRoomHouseFloorVO();
                Integer floorName = s.getKey();
                allRoomHouseFloorVO.setName(floorName.toString());
                List<RoomelEntity> roomelEntities = s.getValue();
                List<AllRoomHouseVO> allRoomHouseVOS = new ArrayList<>();
                roomelEntities.forEach(roomelEntity -> {
                    AllRoomHouseVO allRoomHouseVO = new AllRoomHouseVO();
                    allRoomHouseVO.setRoomFullName(roomelEntity.getFullName());
                    allRoomHouseVO.setRoomHouseId(roomelEntity.getId().toString());
                    allRoomHouseVO.setRoomHouseName(roomelEntity.getRoomHouseName());
                    allRoomHouseVOS.add(allRoomHouseVO);
                });
                allRoomHouseFloorVO.setAllRoomHouseVOS(allRoomHouseVOS);
                allRoomHouseFloorVOS.add(allRoomHouseFloorVO);
            });
            allRoomHouseRespVO.setAllRoomHouseFloorVOS(allRoomHouseFloorVOS);
            allRoomHouseRespVOS.add(allRoomHouseRespVO);
        });

        GetRoomHouseByTenantPhoneRespVO getRoomHouseByTenantPhoneRespVO = new GetRoomHouseByTenantPhoneRespVO()
                .setAllRoomHouseRespVOS(allRoomHouseRespVOS)
                .setApartments(apartments);

        return CommonResult.success(getRoomHouseByTenantPhoneRespVO);
    }

    /**
     * 查看房源信息
     * @param roomHouseId
     * @return
     */
    @Override
    public CommonResult<HouseInfoRespVO> roomHouseInfo(Long roomHouseId) {
        // 查询房间信息
        RoomHouse roomHouse = roomHouseRepository.getById(roomHouseId);
        Assert.isTrue(ObjectUtil.isNotEmpty(roomHouse), "房间信息不存在");
        // 查询户型信息
        RoomHouseType roomHouseType = roomHouseTypeRepository.getById(roomHouse.getRoomHouseTypeId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomHouseType), "户型信息不存在");

        // 查询小区信息
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.getById(roomHouse.getApartmentAreaId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomApartmentArea), "小区信息不存在");

        RoomFloor roomFloor = roomFloorRepository.getById(roomHouse.getFloorId());
        Assert.isTrue(ObjectUtil.isNotEmpty(roomFloor), "楼层信息不存在");
        // 如果是集中式,则查询房型信息
        RoomLayout roomLayout = new RoomLayout();
        if (roomHouse.getIsConcentrated()) {
            roomLayout = roomLayoutRepository.getById(roomHouse.getLayoutId());
            Assert.isTrue(ObjectUtil.isNotEmpty(roomLayout), "房型信息不存在");
        }
        // 整租
        MasterRoomInfo masterRoomInfo = new MasterRoomInfo();
        masterRoomInfo.setIsWhole(roomHouse.getIsWhole());
        masterRoomInfo.setRoomHouseId(roomHouse.getId().toString());
        masterRoomInfo.setNo(roomHouse.getNo());
        masterRoomInfo.setBuildingNo(roomApartmentArea.getBuildingNo());
        masterRoomInfo.setUnitNo(roomApartmentArea.getUnitNo());
        masterRoomInfo.setHouseNo(roomHouse.getHouseNo());
        masterRoomInfo.setLayoutName(roomLayout.getName());
        masterRoomInfo.setLayoutId(roomLayout.getId());
        masterRoomInfo.setBedRoomNum(roomHouseType.getBedRoomNum());
        masterRoomInfo.setLivingRoomNum(roomHouseType.getLivingRoomNum());
        masterRoomInfo.setToiletNum(roomHouseType.getToiletNum());
        masterRoomInfo.setKitchenNum(roomHouseType.getKitchenNum());
        masterRoomInfo.setBalcony(roomHouseType.getBalcony());
        // 集中式取房型面积
        masterRoomInfo.setSpaceMin(roomLayout.getSpaceMin());
        masterRoomInfo.setSpaceMax(roomLayout.getSpaceMax());
        masterRoomInfo.setSpace(roomHouse.getSpace());
        masterRoomInfo.setFloorNum(roomApartmentArea.getFloorNum());
        masterRoomInfo.setGroundFloorNum(roomApartmentArea.getGroundFloorNum());
        masterRoomInfo.setInFloorNum(roomHouse.getFloorNo());
        masterRoomInfo.setToward(roomHouse.getToward());
        masterRoomInfo.setPeopleNum(roomHouse.getPeopleNum());
        masterRoomInfo.setFloorRoomNum(roomFloor.getFloorRoomNum());
        masterRoomInfo.setMonthRental(roomHouse.getMonthRental());
        masterRoomInfo.setIsLock(roomHouse.getIsLock());

        // 如果是合租, 需要设置对应的主房源ID
        if(!roomHouse.getIsWhole()){
            masterRoomInfo.setMainRoomHouseId(roomHouse.getSuperId().toString());
        }

        RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouse.getId());
        masterRoomInfo.setHomeState(roomStateRecord.getState());
        RoomHouseFilings roomHouseFilings = roomHouseFilingsRepository.getByRoomHouseId(roomHouse.getId());
        if (ObjectUtil.isNotEmpty(roomHouseFilings)) {
            masterRoomInfo.setCheckCode(roomHouseFilings.getCheckCode());
        }
        if (StrUtil.isNotEmpty(roomHouse.getCreator())) {
            CommonResult<AdminUserRespDTO> result = adminUserApi.getUser(Long.valueOf(roomHouse.getCreator()));
            if (result.isSuccess()) {
                AdminUserRespDTO adminUserRespDTO = result.getCheckedData();
                masterRoomInfo.setCreateUserName(ObjectUtil.isNotEmpty(adminUserRespDTO) ? adminUserRespDTO.getNickname() : "");
            }
        }
        // 查询备案信息
        RoomHouseInfo roomHouseInfo = roomHouseInfoRepository.getByRoomHouseId(roomHouseId);
        RoomHouseInfoVO roomHouseInfoVO = RoomHouseInfoConvert.INSTANCE.convert(roomHouseInfo);

        HouseInfoRespVO houseInfoRespVO = new HouseInfoRespVO().setRoomHouseInfo(roomHouseInfoVO).setRoomInfo(masterRoomInfo);

        return CommonResult.success(houseInfoRespVO);
    }

    /**
     * 续租合同账单支付后,更新房源的续租合同信息
     * @param roomHouseId
     * @param renewalContractId
     * @param renewalEndTime
     * @return
     */
    @Override
    public CommonResult<Boolean> updateContractInfoByRenewal(Long roomHouseId, Long renewalContractId, LocalDate renewalEndTime) {
        return roomelEntityRepository.updateContractInfoByRenewal(roomHouseId, renewalContractId, renewalEndTime);
    }

    @Override
    public List<RoomHouse> selectListByIds(List<String> ids) {
        return roomHouseRepository.selectListByIds(ids);
    }

    @Override
    public CommonResult<Boolean> isCleanRoomHouseEdit(Long roomHouseId, Boolean isClean) {
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouseId);
//        roomelUpdateReqVO.setHouseState(RentStatusEnum.CLEAR.getValue());
        roomelUpdateReqVO.setIsClean(isClean);
        roomEsProducer.updateRoomEl(roomelUpdateReqVO);
        log.info("ES更新的参数V0: message = " + roomelUpdateReqVO);
        return roomHouseRepository.isCleanRoomHouseEdit(roomHouseId,isClean);
    }

    @Override
    public CommonResult<Boolean> isRepairRoomHouseEdit(Long roomHouseId, Boolean isRepair) {
        RoomelUpdateReqVO vo = new RoomelUpdateReqVO();
        vo.setId(roomHouseId);
        vo.setIsRepair(isRepair);
        log.info("ES更新的参数V0: message = " + vo);
        roomEsProducer.updateRoomEl(vo);
        return roomHouseRepository.isRepairRoomHouseEdit(roomHouseId,isRepair);
    }


    /**
     * 分散式房源出租形式变更
     * @param editReqVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> noConcentratedEditRentalMethod(NoConcentratedRoomHouseEditReqVO editReqVO) {
        // 获取主房源信息
        RoomHouse masterRoomHouse = roomHouseRepository.getById(editReqVO.getRoomHouseId());

        if(masterRoomHouse.getIsConcentrated()){
            throw new ServiceException(CONCENTRATED_DOES_NOT_SUPPORT_SWITCHING_RENTAL_FORMS);
        }

        Assert.isTrue(ObjectUtil.isNotEmpty(masterRoomHouse), "房源信息不存在");
        if (ObjectUtil.isNotEmpty(masterRoomHouse.getSuperId())) {
            masterRoomHouse = roomHouseRepository.getById(masterRoomHouse.getSuperId());
        }
        RoomApartmentArea roomApartmentArea = roomApartmentAreaRepository.myGetById(masterRoomHouse.getApartmentAreaId());

        Long tenantId = masterRoomHouse.getTenantId();
        // 校验公寓信息
        Apartment apartment = apartmentRepository.getById(masterRoomHouse.getApartmentId());
        Assert.isTrue(ObjectUtil.isNotEmpty(apartment), "公寓信息不存在");
        // 户型信息是否变更
        NoConcentratedEditRoomHouseDto masterRoomInfo = editReqVO.getMasterRoomInfo();
        RoomHouseType roomHouseType = houseTypeService.getRoomHouseType(masterRoomInfo.getBedRoomNum(),
                masterRoomInfo.getLivingRoomNum(),
                masterRoomInfo.getToiletNum(),
                masterRoomInfo.getKitchenNum(),
                masterRoomInfo.getBalcony());
        // 修改主房间信息
        masterRoomHouse.setSpace(editReqVO.getMasterRoomInfo().getSpace());
        masterRoomHouse.setToward(editReqVO.getMasterRoomInfo().getToward());
        masterRoomHouse.setPicUrl(editReqVO.getPicUrl());
        masterRoomHouse.setVideoUrl(editReqVO.getVideoUrl());
        masterRoomHouse.setVrUrl(editReqVO.getVrUrl());
        masterRoomHouse.setVrPicUrl(editReqVO.getVrPicUrl());
        masterRoomHouse.setPublicFacilities(editReqVO.getRoomEquipment());
        masterRoomHouse.setPeopleNum(editReqVO.getMasterRoomInfo().getPeopleNum());
        masterRoomHouse.setDecoration(editReqVO.getRecordInfoDto().getDecoration());
        masterRoomHouse.setRoomHouseTypeId(roomHouseType.getId());

        // 更新ES数据
        List<RoomelUpdateReqVO> roomelUpdateReqVOS = new ArrayList<>();
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(masterRoomHouse.getId());
        roomelUpdateReqVO.setRoomHouseTypeId(masterRoomHouse.getRoomHouseTypeId());
        roomelUpdateReqVO.setRoomHouseTypeName(roomHouseType.getName());
        roomelUpdateReqVO.setSpace(masterRoomHouse.getSpace());
        roomelUpdateReqVO.setDecoration(masterRoomHouse.getDecoration());
        roomelUpdateReqVO.setPublicFacilities(masterRoomHouse.getPublicFacilities());
        roomelUpdateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
        roomelUpdateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
        roomelUpdateReqVO.setToiletNum(roomHouseType.getToiletNum());
        roomelUpdateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
        roomelUpdateReqVO.setBalcony(roomHouseType.getBalcony());
        roomelUpdateReqVO.setToward(masterRoomHouse.getToward());

        // 查询备案信息
        RoomHouseInfo roomHouseInfo = roomHouseInfoRepository.getByRoomHouseId(masterRoomHouse.getId());
        if (ObjectUtil.isEmpty(roomHouseInfo)) {
            roomHouseInfo = new RoomHouseInfo();
        }
        // 更新备案信息
        RecordInfoDto recordInfoDto = editReqVO.getRecordInfoDto();
        BeanUtil.copyProperties(recordInfoDto, roomHouseInfo);
        roomHouseInfo.setRoomHouseId(masterRoomHouse.getId());
        roomHouseInfoRepository.updateById(roomHouseInfo);
        roomHouseInfo.setId(null);

        // 整租变合租
        if(masterRoomHouse.getIsWhole() && !editReqVO.getIsWhole()){
            // 检查是否为空房
            RoomStateRecord currentState = roomStateRecordService.getByRoomIdAndIsCurrentState(masterRoomHouse.getId());
            if(!RentStatusEnum.EMPTY.getValue().equals(currentState.getState())){
                throw new ServiceException(THERE_ARE_NON_VACANT_LISTINGS_ERROR);
            }

            // 主房源改为合租, 保存
            masterRoomHouse.setIsWhole(false);
            masterRoomHouse.setIsStop(true);
            roomHouseRepository.updateById(masterRoomHouse);

            // 主房源设为停用
            roomelUpdateReqVO.setIsStop(masterRoomHouse.getIsStop());
            roomelUpdateReqVO.setIsWhole(masterRoomHouse.getIsWhole());
            roomelUpdateReqVOS.add(roomelUpdateReqVO);

            List<RoomelCreateReqVO> roomelCreateReqVOS = new ArrayList<>();

            // 校验子房源信息
            List<NoConcentratedRoomInfoDto> roomInfos = editReqVO.getSlaveRoomInfo();
            RoomHouse finalMasterRoomHouse = masterRoomHouse;
            NoConcentratedRoomInfoDto noConcentratedRoomInfoDto = roomInfos.stream().filter(p -> p.getRoomHouseNo().equals(finalMasterRoomHouse.getHouseNo())).findFirst().orElse(null);
            if (ObjectUtil.isNotEmpty(noConcentratedRoomInfoDto)) {
                throw new ServiceException(new ErrorCode(20002, "房间名不能和室号重复"));
            }
            List<String> roomNames = roomInfos.stream().map(NoConcentratedRoomInfoDto::getRoomHouseNo).distinct().collect(Collectors.toList());
            if (roomNames.size() < roomInfos.size()) {
                throw new ServiceException(new ErrorCode(20001, "房间名不能重复"));
            }

            // 查询该房源之前有没有子房源
            List<RoomHouse> slaveRoomHouses = roomHouseRepository.getBySuperId(masterRoomHouse.getId()).getCheckedData();
            if(ObjectUtil.isNotEmpty(slaveRoomHouses)){

                // 有历史子房源, 则将历史子房源设为非停用, 更新数据库, 更新es, 更新备案信息即可
                List<RoomHouse> roomHouses = new ArrayList<>();
                List<RoomHouseInfo> roomHouseInfos = new ArrayList<>();
                List<RoomHouse> newAddRoomHouses = new ArrayList<>();
                RoomHouseInfo finalRoomHouseInfo = roomHouseInfo;
                roomInfos.stream().forEach(slaveRoomHouse -> {
                    // 可能有新增的子房间
                    if(ObjectUtil.isNotEmpty(slaveRoomHouse.getRoomHouseId())){
                        // 历史的子房间
                        RoomHouse roomHouse = new RoomHouse();
                        roomHouse.setId(slaveRoomHouse.getRoomHouseId());
                        roomHouse.setName(finalMasterRoomHouse.getName() + "-" + slaveRoomHouse.getRoomHouseNo());
                        roomHouse.setRoomType(slaveRoomHouse.getRoomType());
                        roomHouse.setSpace(slaveRoomHouse.getSpace());
                        roomHouse.setToward(slaveRoomHouse.getToward());
                        roomHouse.setPeopleNum(slaveRoomHouse.getPeopleNum());
                        roomHouse.setRoomHouseTypeId(roomHouseType.getId());
                        roomHouse.setIsStop(false);
                        roomHouse.setIsLastStop(false);
                        roomHouses.add(roomHouse);
                        // 更新子房源信息到es
                        RoomelUpdateReqVO slaveRoomelUpdateReqVO = new RoomelUpdateReqVO();
                        slaveRoomelUpdateReqVO.setId(roomHouse.getId());
                        slaveRoomelUpdateReqVO.setIsStop(roomHouse.getIsStop());
                        slaveRoomelUpdateReqVO.setRoomHouseName(roomHouse.getName());
                        slaveRoomelUpdateReqVO.setSpace(roomHouse.getSpace());
                        slaveRoomelUpdateReqVO.setToward(roomHouse.getToward());
                        slaveRoomelUpdateReqVO.setRoomType(roomHouse.getRoomType());
                        slaveRoomelUpdateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
                        slaveRoomelUpdateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
                        slaveRoomelUpdateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
                        slaveRoomelUpdateReqVO.setToiletNum(roomHouseType.getToiletNum());
                        slaveRoomelUpdateReqVO.setBalcony(roomHouseType.getBalcony());
                        slaveRoomelUpdateReqVO.setRoomHouseTypeId(roomHouseType.getId());
                        slaveRoomelUpdateReqVO.setRoomHouseTypeName(roomHouseType.getName());
                        roomelUpdateReqVOS.add(slaveRoomelUpdateReqVO);

                        // 修改子房间的备案信息
                        RoomHouseInfo houseInfo = roomHouseInfoRepository.getByRoomHouseId(roomHouse.getId());
                        if (ObjectUtil.isEmpty(houseInfo)) {
                            houseInfo = new RoomHouseInfo();
                        }
                        // 更新备案信息
                        BeanUtil.copyProperties(recordInfoDto, houseInfo);
                        houseInfo.setRoomHouseId(roomHouse.getId());
                        roomHouseInfos.add(houseInfo);
                    }else{
                        // 新增的房间
                        RoomHouse roomHouse = new RoomHouse();
                        roomHouse.setId(IdUtil.getSnowflakeNextId());
                        roomHouse.setName(finalMasterRoomHouse.getName() + "-" + slaveRoomHouse.getRoomHouseNo());
                        roomHouse.setNo(codeUtil.nextCode("FJ"));
                        roomHouse.setProvince(finalMasterRoomHouse.getProvince());
                        roomHouse.setCity(finalMasterRoomHouse.getCity());
                        roomHouse.setDistrict(finalMasterRoomHouse.getDistrict());
                        roomHouse.setStreet(finalMasterRoomHouse.getStreet());
                        roomHouse.setAddress(finalMasterRoomHouse.getAddress());
                        roomHouse.setArea(finalMasterRoomHouse.getArea());
                        roomHouse.setSpace(slaveRoomHouse.getSpace());
                        roomHouse.setApartmentId(finalMasterRoomHouse.getApartmentId());
                        roomHouse.setHouseNo(slaveRoomHouse.getRoomHouseNo());
                        roomHouse.setIsWhole(finalMasterRoomHouse.getIsWhole());
                        roomHouse.setRoomNum(roomInfos.size());
                        roomHouse.setIsStop(false);
                        roomHouse.setIsLastStop(false);
                        roomHouse.setFloorId(finalMasterRoomHouse.getFloorId());
                        roomHouse.setFloorNo(finalMasterRoomHouse.getFloorNo());
                        roomHouse.setDecoration(recordInfoDto.getDecoration());
                        roomHouse.setToward(slaveRoomHouse.getToward());
                        roomHouse.setIsConcentrated(false);
                        roomHouse.setApartmentAreaId(finalMasterRoomHouse.getApartmentAreaId());
                        roomHouse.setRoomHouseTypeId(roomHouseType.getId());
                        roomHouse.setSuperId(finalMasterRoomHouse.getId());
                        roomHouse.setPeopleNum(slaveRoomHouse.getPeopleNum());
                        roomHouse.setRoomType(slaveRoomHouse.getRoomType());
                        roomHouse.setIsLock(false);
                        roomHouse.setDeptId(finalMasterRoomHouse.getDeptId());
                        roomHouse.setBuildingNo(finalMasterRoomHouse.getBuildingNo());
                        roomHouse.setUnitNo(finalMasterRoomHouse.getUnitNo());
                        roomHouse.setPicUrl(finalMasterRoomHouse.getPicUrl());
                        roomHouse.setVideoUrl(finalMasterRoomHouse.getVideoUrl());
                        roomHouse.setVrPicUrl(finalMasterRoomHouse.getVrPicUrl());
                        roomHouse.setVrUrl(finalMasterRoomHouse.getVrUrl());
                        roomHouseRepository.save(roomHouse);
                        newAddRoomHouses.add(roomHouse);


                        // 创建房源时，加入一条房态, 分散式房源房态默认冻结
                        RoomStateRecord roomStateRecord = new RoomStateRecord();
                        roomStateRecord.setRoomId(roomHouse.getId());
                        roomStateRecord.setIsCurrentState(true);
                        roomStateRecord.setState(RentStatusEnum.FREEZE.getValue());
                        roomStateRecordRepository.save(roomStateRecord);

                        // 保存子房间的备案信息
                        finalRoomHouseInfo.setRoomHouseId(roomHouse.getId());
                        finalRoomHouseInfo.setId(null);
                        roomHouseInfoRepository.save(finalRoomHouseInfo);

                        // 组装ES所需数据
                        StringBuilder name = new StringBuilder();
                        name.append(roomHouse.getArea());
                        name.append(roomApartmentArea.getBuildingNo());
                        name.append("栋");
                        if (!roomHouse.getIsConcentrated()) {
                            name.append(roomApartmentArea.getUnitNo());
                            name.append("单元");
                        }
                        name.append(roomHouse.getName());

                        RoomelCreateReqVO roomelCreateReqVO = new RoomelCreateReqVO();
                        roomelCreateReqVO.setId(roomHouse.getId());
                        roomelCreateReqVO.setFullName(name.toString());
                        roomelCreateReqVO.setSuperId(roomHouse.getSuperId());
                        roomelCreateReqVO.setApartmentAreaId(roomApartmentArea.getId());
                        roomelCreateReqVO.setApartmentAreaName(roomApartmentArea.getArea());
                        roomelCreateReqVO.setApartmentName(apartment.getName());
                        roomelCreateReqVO.setApartmentId(apartment.getId());
                        roomelCreateReqVO.setIsConcentrated(roomApartmentArea.getIsConcentrated());
                        roomelCreateReqVO.setApartmentAreaLat(roomApartmentArea.getLatitude());
                        roomelCreateReqVO.setApartmentAreaLon(roomApartmentArea.getLongitude());
                        roomelCreateReqVO.setApartmentLat(apartment.getLatitude());
                        roomelCreateReqVO.setApartmentLon(apartment.getLongitude());
                        roomelCreateReqVO.setSourceType(apartment.getSourceType());
                        roomelCreateReqVO.setFloorId(roomHouse.getFloorId());
                        roomelCreateReqVO.setBuildingNo(roomApartmentArea.getBuildingNo());
                        roomelCreateReqVO.setUnitNo(roomApartmentArea.getUnitNo());
                        roomelCreateReqVO.setFloorNo(Integer.valueOf(roomHouse.getFloorNo()));
                        roomelCreateReqVO.setFloorSum(roomApartmentArea.getFloorNum());
                        roomelCreateReqVO.setCity(roomApartmentArea.getCity());
                        roomelCreateReqVO.setDistrict(roomApartmentArea.getDistrict());
                        roomelCreateReqVO.setStreet(roomApartmentArea.getStreet());
                        roomelCreateReqVO.setAddress(roomApartmentArea.getAddress());
                        roomelCreateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
                        roomelCreateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
                        roomelCreateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
                        roomelCreateReqVO.setToiletNum(roomHouseType.getToiletNum());
                        roomelCreateReqVO.setBalcony(roomHouseType.getBalcony());
                        roomelCreateReqVO.setRoomHouseTypeId(roomHouseType.getId());
                        roomelCreateReqVO.setRoomHouseTypeName(roomHouseType.getName());
                        roomelCreateReqVO.setFacetoType(roomHouse.getToward());
                        roomelCreateReqVO.setIsWhole(roomHouse.getIsWhole());
                        roomelCreateReqVO.setSpace(roomHouse.getSpace());
                        roomelCreateReqVO.setDecoration(roomHouse.getDecoration());
                        roomelCreateReqVO.setHouseState(RentStatusEnum.FREEZE.getValue());
                        roomelCreateReqVO.setRoomHouseName(roomHouse.getName());
                        roomelCreateReqVO.setIsScheduled(false);
                        roomelCreateReqVO.setTenantId(tenantId);
                        roomelCreateReqVO.setRoomHouseNo(roomHouse.getNo());
                        roomelCreateReqVO.setHouseNo(roomHouse.getHouseNo());
                        roomelCreateReqVO.setIsLock(false);
                        roomelCreateReqVO.setIsStop(false);
                        // 引用主房源的独立设施
                        roomelCreateReqVO.setPublicFacilities(finalMasterRoomHouse.getPublicFacilities());
                        roomelCreateReqVO.setCreateTime(LocalDateTime.now());
                        roomelCreateReqVO.setDeptId(roomHouse.getDeptId());
                        roomelCreateReqVO.setRoomType(roomHouse.getRoomType());
                        roomelCreateReqVO.setRoomAreaId(roomApartmentArea.getRoomAreaId());
                        roomelCreateReqVO.setToward(roomHouse.getToward());
                        roomelCreateReqVOS.add(roomelCreateReqVO);
                    }
                });
                roomHouseRepository.updateBatchById(roomHouses);
                roomHouseInfoRepository.updateBatchById(roomHouseInfos);

                // 处理主房源资产, 主房源资产优先挂到主卧，其次次卧
                RoomHouse roomHouse = slaveRoomHouses.stream().filter(p -> RoomTypeEnum.ZW.getValue().equals(p.getRoomType())).findFirst().orElse(null);
                if(ObjectUtil.isEmpty(roomHouse)){
                    roomHouse = slaveRoomHouses.stream().filter(p -> RoomTypeEnum.CW.getValue().equals(p.getRoomType())).findFirst().orElse(null);
                }
                if(ObjectUtil.isEmpty(roomHouse)){
                    throw new ServiceException(SWITCH_RENTAL_FORMATS_ERROR);
                }
                // 主房源的资产
                List<RoomEquipment> roomEquipments = roomEquipmentRepository.getByRoomIds(Arrays.asList(masterRoomHouse.getId()));
                Long roomHouseId = roomHouse.getId();
                // 全部归属到主卧/次卧上
                roomEquipments.stream().forEach(p -> p.setRoomId(roomHouseId));
                roomEquipmentRepository.updateBatchById(roomEquipments);
                // 更新房源信息到es
                if (ObjectUtil.isNotEmpty(roomelUpdateReqVOS)) {
                    roomEsProducer.updateBatchRoomEl(roomelUpdateReqVOS);
                }
                // 推送新增的房源信息到es
                if (ObjectUtil.isNotEmpty(roomelCreateReqVOS)) {
                    roomEsProducer.ListAddRoomEl(roomelCreateReqVOS);
                }
                // 主房源更新为冻结
                this.roomFreeze(masterRoomHouse.getId());
                // 更新监管平台备案信息
                sendFilings(masterRoomHouse.getTenantId(), roomApartmentArea, roomHouseInfo, roomHouseType, masterRoomHouse, roomInfos);
                // 结束返回
                return CommonResult.success(Boolean.TRUE);

            }

            // 增加子房源信息
            Assert.isFalse(editReqVO.getIsWhole() && ObjectUtil.isNotEmpty(roomInfos), "整租时不能添加子房间");
            RoomHouseInfo finalRoomHouseInfo = roomHouseInfo;
            List<RoomHouse> slaveRoomHouseList = new ArrayList<>();
            roomInfos.stream().forEach(roomInfo -> {
                RoomHouse roomHouse = new RoomHouse();
                roomHouse.setId(IdUtil.getSnowflakeNextId());
                roomHouse.setName(finalMasterRoomHouse.getName() + "-" + roomInfo.getRoomHouseNo());
                roomHouse.setNo(codeUtil.nextCode("FJ"));
                roomHouse.setProvince(finalMasterRoomHouse.getProvince());
                roomHouse.setCity(finalMasterRoomHouse.getCity());
                roomHouse.setDistrict(finalMasterRoomHouse.getDistrict());
                roomHouse.setStreet(finalMasterRoomHouse.getStreet());
                roomHouse.setAddress(finalMasterRoomHouse.getAddress());
                roomHouse.setArea(finalMasterRoomHouse.getArea());
                roomHouse.setSpace(roomInfo.getSpace());
                roomHouse.setApartmentId(finalMasterRoomHouse.getApartmentId());
                roomHouse.setHouseNo(roomInfo.getRoomHouseNo());
                roomHouse.setIsWhole(finalMasterRoomHouse.getIsWhole());
                roomHouse.setRoomNum(roomInfos.size());
                roomHouse.setIsStop(false);
                roomHouse.setIsLastStop(false);
                roomHouse.setFloorId(finalMasterRoomHouse.getFloorId());
                roomHouse.setFloorNo(finalMasterRoomHouse.getFloorNo());
                roomHouse.setDecoration(recordInfoDto.getDecoration());
                roomHouse.setToward(roomInfo.getToward());
                roomHouse.setIsConcentrated(false);
                roomHouse.setApartmentAreaId(roomApartmentArea.getId());
                roomHouse.setRoomHouseTypeId(roomHouseType.getId());
                roomHouse.setSuperId(finalMasterRoomHouse.getId());
                roomHouse.setPeopleNum(roomInfo.getPeopleNum());
                roomHouse.setRoomType(roomInfo.getRoomType());
                roomHouse.setIsLock(false);
                roomHouse.setDeptId(finalMasterRoomHouse.getDeptId());
                roomHouse.setBuildingNo(roomApartmentArea.getBuildingNo());
                roomHouse.setUnitNo(roomApartmentArea.getUnitNo());
                roomHouse.setPicUrl(finalMasterRoomHouse.getPicUrl());
                roomHouse.setVideoUrl(finalMasterRoomHouse.getVideoUrl());
                roomHouse.setVrPicUrl(finalMasterRoomHouse.getVrPicUrl());
                roomHouse.setVrUrl(finalMasterRoomHouse.getVrUrl());
                roomHouseRepository.save(roomHouse);
                slaveRoomHouseList.add(roomHouse);

                // 创建房源时，加入一条房态, 分散式房源房态默认冻结
                RoomStateRecord roomStateRecord = new RoomStateRecord();
                roomStateRecord.setRoomId(roomHouse.getId());
                roomStateRecord.setIsCurrentState(true);
                roomStateRecord.setState(RentStatusEnum.FREEZE.getValue());
                roomStateRecordRepository.save(roomStateRecord);

                // 保存子房间的备案信息
                finalRoomHouseInfo.setRoomHouseId(roomHouse.getId());
                finalRoomHouseInfo.setId(null);
                roomHouseInfoRepository.save(finalRoomHouseInfo);

                // 组装ES所需数据
                StringBuilder name = new StringBuilder();
                name.append(roomHouse.getArea());
                name.append(roomApartmentArea.getBuildingNo());
                name.append("栋");
                if (!roomHouse.getIsConcentrated()) {
                    name.append(roomApartmentArea.getUnitNo());
                    name.append("单元");
                }
                name.append(roomHouse.getName());

                RoomelCreateReqVO roomelCreateReqVO = new RoomelCreateReqVO();
                roomelCreateReqVO.setId(roomHouse.getId());
                roomelCreateReqVO.setFullName(name.toString());
                roomelCreateReqVO.setSuperId(roomHouse.getSuperId());
                roomelCreateReqVO.setApartmentAreaId(roomApartmentArea.getId());
                roomelCreateReqVO.setApartmentAreaName(roomApartmentArea.getArea());
                roomelCreateReqVO.setApartmentName(apartment.getName());
                roomelCreateReqVO.setApartmentId(apartment.getId());
                roomelCreateReqVO.setIsConcentrated(roomApartmentArea.getIsConcentrated());
                roomelCreateReqVO.setApartmentAreaLat(roomApartmentArea.getLatitude());
                roomelCreateReqVO.setApartmentAreaLon(roomApartmentArea.getLongitude());
                roomelCreateReqVO.setApartmentLat(apartment.getLatitude());
                roomelCreateReqVO.setApartmentLon(apartment.getLongitude());
                roomelCreateReqVO.setSourceType(apartment.getSourceType());
                roomelCreateReqVO.setFloorId(roomHouse.getFloorId());
                roomelCreateReqVO.setBuildingNo(roomApartmentArea.getBuildingNo());
                roomelCreateReqVO.setUnitNo(roomApartmentArea.getUnitNo());
                roomelCreateReqVO.setFloorNo(Integer.valueOf(roomHouse.getFloorNo()));
                roomelCreateReqVO.setFloorSum(roomApartmentArea.getFloorNum());
                roomelCreateReqVO.setCity(roomApartmentArea.getCity());
                roomelCreateReqVO.setDistrict(roomApartmentArea.getDistrict());
                roomelCreateReqVO.setStreet(roomApartmentArea.getStreet());
                roomelCreateReqVO.setAddress(roomApartmentArea.getAddress());
                roomelCreateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
                roomelCreateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
                roomelCreateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
                roomelCreateReqVO.setToiletNum(roomHouseType.getToiletNum());
                roomelCreateReqVO.setBalcony(roomHouseType.getBalcony());
                roomelCreateReqVO.setRoomHouseTypeId(roomHouseType.getId());
                roomelCreateReqVO.setRoomHouseTypeName(roomHouseType.getName());
                roomelCreateReqVO.setFacetoType(roomHouse.getToward());
                roomelCreateReqVO.setIsWhole(roomHouse.getIsWhole());
                roomelCreateReqVO.setSpace(roomHouse.getSpace());
                roomelCreateReqVO.setDecoration(roomHouse.getDecoration());
                roomelCreateReqVO.setHouseState(RentStatusEnum.FREEZE.getValue());
                roomelCreateReqVO.setRoomHouseName(roomHouse.getName());
                roomelCreateReqVO.setIsScheduled(false);
                roomelCreateReqVO.setTenantId(tenantId);
                roomelCreateReqVO.setRoomHouseNo(roomHouse.getNo());
                roomelCreateReqVO.setHouseNo(roomHouse.getHouseNo());
                roomelCreateReqVO.setIsLock(false);
                roomelCreateReqVO.setIsStop(false);
                // 引用主房源的独立设施
                roomelCreateReqVO.setPublicFacilities(finalMasterRoomHouse.getPublicFacilities());
                roomelCreateReqVO.setCreateTime(LocalDateTime.now());
                roomelCreateReqVO.setDeptId(roomHouse.getDeptId());
                roomelCreateReqVO.setRoomType(roomHouse.getRoomType());
                roomelCreateReqVO.setRoomAreaId(roomApartmentArea.getRoomAreaId());
                roomelCreateReqVO.setToward(roomHouse.getToward());
                roomelCreateReqVOS.add(roomelCreateReqVO);
            });

            // 处理主房源资产, 主房源资产优先挂到主卧，其次次卧
            RoomHouse roomHouse = slaveRoomHouseList.stream().filter(p -> RoomTypeEnum.ZW.getValue().equals(p.getRoomType())).findFirst().orElse(null);
            if(ObjectUtil.isEmpty(roomHouse)){
                roomHouse = slaveRoomHouseList.stream().filter(p -> RoomTypeEnum.CW.getValue().equals(p.getRoomType())).findFirst().orElse(null);
            }
            if(ObjectUtil.isEmpty(roomHouse)){
                throw new ServiceException(SWITCH_RENTAL_FORMATS_ERROR);
            }

            // 主房源的资产
            List<RoomEquipment> roomEquipments = roomEquipmentRepository.getByRoomIds(Arrays.asList(masterRoomHouse.getId()));
            Long roomHouseId = roomHouse.getId();
            // 全部归属到主卧/次卧上
            if(ObjectUtil.isNotEmpty(roomEquipments)){
                roomEquipments.stream().forEach(p -> p.setRoomId(roomHouseId));
                roomEquipmentRepository.updateBatchById(roomEquipments);
            }

            // 推送房源信息到es
            if (ObjectUtil.isNotEmpty(roomelCreateReqVOS)) {
                roomEsProducer.ListAddRoomEl(roomelCreateReqVOS);
            }
            // 更新房源信息到es
            if (ObjectUtil.isNotEmpty(roomelUpdateReqVOS)) {
                roomEsProducer.updateBatchRoomEl(roomelUpdateReqVOS);
            }
            // 主房源更新为冻结
            this.roomFreeze(masterRoomHouse.getId());
            // 备案信息推送监管平台更新数据
            // 更新监管平台备案信息
            sendFilings(masterRoomHouse.getTenantId(), roomApartmentArea, roomHouseInfo, roomHouseType, masterRoomHouse, roomInfos);

        }else if(!masterRoomHouse.getIsWhole() && editReqVO.getIsWhole()){
            // 合租变整租
            // 子房间全部隐藏, 主房源改为整租,
            masterRoomHouse.setIsWhole(true);
            masterRoomHouse.setIsStop(false);
            roomHouseRepository.updateById(masterRoomHouse);
            roomelUpdateReqVO.setIsStop(masterRoomHouse.getIsStop());
            roomelUpdateReqVO.setIsWhole(masterRoomHouse.getIsWhole());
            roomelUpdateReqVOS.add(roomelUpdateReqVO);
            // 拿到所有的子房源
            List<RoomHouse> slaveRoomHouses = roomHouseRepository.getBySuperId(masterRoomHouse.getId()).getCheckedData();
            RoomHouse GGQYRoom = slaveRoomHouses.stream().filter(p -> RoomTypeEnum.GGQY.getValue().equals(p.getRoomType())).findFirst().orElse(new RoomHouse());
            GGQYRoom.setRoomHouseTypeId(roomHouseType.getId());
            // 过滤公区
            slaveRoomHouses = slaveRoomHouses.stream().filter(p -> !RoomTypeEnum.GGQY.getValue().equals(p.getRoomType())).collect(Collectors.toList());
            slaveRoomHouses.stream().forEach(slaveRoomHouse -> {
                // 检查是否为空房, 并且需要是未锁定
                RoomStateRecord currentState = roomStateRecordService.getByRoomIdAndIsCurrentState(slaveRoomHouse.getId());
                if(!RentStatusEnum.EMPTY.getValue().equals(currentState.getState()) || slaveRoomHouse.getIsLock()){
                    throw new ServiceException(THERE_ARE_NON_VACANT_LISTINGS_ERROR);
                }
            });
            List<RoomHouseInfo> roomHouseInfos = new ArrayList<>();
            slaveRoomHouses.stream().forEach(roomHouse -> {
                // 上一次停用的子房间改为非上一次停用
                if(ObjectUtil.isEmpty(roomHouse.getIsLastStop()) ||
                        (ObjectUtil.isNotEmpty(roomHouse.getIsLastStop()) && !roomHouse.getIsLastStop())){
                    roomHouse.setIsStop(true);
                    roomHouse.setIsLastStop(true);
                    roomHouse.setRoomHouseTypeId(roomHouseType.getId());
                    // 房态改为冻结
                    this.roomFreeze(roomHouse.getId());
                    // 更新子房源的备案信息
                    RoomHouseInfo houseInfo = roomHouseInfoRepository.getByRoomHouseId(roomHouse.getId());
                    if (ObjectUtil.isEmpty(houseInfo)) {
                        houseInfo = new RoomHouseInfo();
                    }
                    // 更新备案信息
                    BeanUtil.copyProperties(recordInfoDto, houseInfo);
                    houseInfo.setRoomHouseId(roomHouse.getId());
                    roomHouseInfos.add(houseInfo);

                    // 更新子房源信息到es
                    RoomelUpdateReqVO slaveRoomelUpdateReqVO = new RoomelUpdateReqVO();
                    slaveRoomelUpdateReqVO.setId(roomHouse.getId());
                    slaveRoomelUpdateReqVO.setIsStop(roomHouse.getIsStop());
                    roomelUpdateReqVOS.add(slaveRoomelUpdateReqVO);
                }else{
                    roomHouse.setIsLastStop(false);
                }
            });
            if(ObjectUtil.isNotEmpty(GGQYRoom.getId())){
                slaveRoomHouses.add(GGQYRoom);
            }
            // 子房间更新为停用
            roomHouseRepository.updateBatchById(slaveRoomHouses);
            roomHouseInfoRepository.updateBatchById(roomHouseInfos);
            // 主房源在添加房源的接口中已经备案了， 这里不需要再备案

            // 处理子房源资产，全部挂到主房源
            List<Long> roomHouseIds = slaveRoomHouses.stream().map(RoomHouse::getId).collect(Collectors.toList());
            // 所有子房源的资产
            List<RoomEquipment> roomEquipments = roomEquipmentRepository.getByRoomIds(roomHouseIds);
            Long masterRoomHouseId = masterRoomHouse.getId();
            if(ObjectUtil.isNotEmpty(roomEquipments)){
                roomEquipments.stream().forEach(p -> p.setRoomId(masterRoomHouseId));
                // 更新资产信息
                roomEquipmentRepository.updateBatchById(roomEquipments);
            }
            // 更新房源信息到es
            if (ObjectUtil.isNotEmpty(roomelUpdateReqVOS)) {
                roomEsProducer.updateBatchRoomEl(roomelUpdateReqVOS);
            }
            // 更新监管平台备案信息
            sendFilings(masterRoomHouse.getTenantId(), roomApartmentArea, roomHouseInfo, roomHouseType, masterRoomHouse, new ArrayList<>());
        }

        return CommonResult.success(Boolean.TRUE);
    }

    /**
     * 切换为合租时获取子房源信息
     * @param roomHouseId
     * @return
     */
    @Override
    public CommonResult<List<SlaveRoomInfo>> getSubListingsWhenSwitchingToSharedApartments(Long roomHouseId) {
        // 获取主房源信息
        RoomHouse masterRoomHouse = roomHouseRepository.getById(roomHouseId);
        Assert.isTrue(ObjectUtil.isNotEmpty(masterRoomHouse), "房源信息不存在");
        // 获取子房源信息
        List<RoomHouse> roomHouseList = roomHouseRepository.getBySuperId(ObjectUtil.isNotEmpty(masterRoomHouse.getSuperId()) ? masterRoomHouse.getSuperId() : masterRoomHouse.getId()).getCheckedData();
        // 过滤出上次停用的
        roomHouseList = roomHouseList.stream().filter(p -> p.getIsLastStop() || RoomTypeEnum.GGQY.getValue().equals(p.getRoomType())).collect(Collectors.toList());
        List<SlaveRoomInfo> slaveRoomInfos = new ArrayList<>();
        for (RoomHouse room : roomHouseList) {
            SlaveRoomInfo slaveRoomInfo = new SlaveRoomInfo();
            slaveRoomInfo.setRoomHouseId(room.getId());
            slaveRoomInfo.setRoomHouseNo(room.getHouseNo());
            slaveRoomInfo.setRoomType(room.getRoomType());
            slaveRoomInfo.setSpace(room.getSpace());
            slaveRoomInfo.setToward(room.getToward());
            slaveRoomInfo.setPeopleNum(room.getPeopleNum());
            slaveRoomInfos.add(slaveRoomInfo);
        }
        slaveRoomInfos = slaveRoomInfos.stream().sorted(Comparator.comparing(SlaveRoomInfo::getRoomType)).collect(Collectors.toList());
        return CommonResult.success(slaveRoomInfos);
    }

    /**
     * 样板房切换
     * @param roomHouseId
     * @return
     */
    @Override
    public CommonResult<Boolean> screed(Long roomHouseId) {
        // 检查房源状态
        roomHouseRepository.myGetById(roomHouseId);
        // 获取当前房态
        RoomStateRecord roomStateRecord = roomStateRecordService.getByRoomIdAndIsCurrentState(roomHouseId);
        String roomState = "";
        if (roomStateRecord.getState().equals(RentStatusEnum.EMPTY.getValue())) {
            // 如果是空房, 则改为样板房
            roomState = RentStatusEnum.SCREED.getValue();
            roomStateRecordService.saveRecord(roomHouseId, RentStatusEnum.SCREED.getValue());
        } else if (RentStatusEnum.SCREED.getValue().equals(roomStateRecord.getState())) {
            // 若是是样板房, 则改为空房
            roomState = RentStatusEnum.EMPTY.getValue();
            roomStateRecordService.saveRecord(roomHouseId, RentStatusEnum.EMPTY.getValue());
        } else {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "房态修改异常");
        }
        // 同步房态到es
        RoomelUpdateReqVO roomelUpdateReqVO = new RoomelUpdateReqVO();
        roomelUpdateReqVO.setId(roomHouseId);
        roomelUpdateReqVO.setHouseState(roomState);
        roomEsProducer.updateRoomEl(roomelUpdateReqVO);
        return CommonResult.success(Boolean.TRUE);
    }


    /**
     * 保存所有楼层和房间信息
     *
     * @param concentratedAddVO
     * @param roomApartmentArea
     * @param roomInfo
     * @param tenantId
     */
    private void saveFloorAndRoomHouse(ConcentratedAddVO concentratedAddVO, RoomApartmentArea roomApartmentArea, Map<Integer, List<RoomInfoDto>> roomInfo, Apartment apartment, RoomArea roomArea, Long tenantId) {
        // 备案信息
        RecordInfoDto recordInfoDto = concentratedAddVO.getRecordInfoDto();
        RoomHouseInfo roomHouseInfo = RoomHouseInfoConvert.INSTANCE.convert(recordInfoDto);
        List<RoomelCreateReqVO> roomelCreateReqVOS = new ArrayList<>();
        RoomApartmentArea finalRoomApartmentArea = roomApartmentArea;
        roomInfo.entrySet().stream().forEach(floor -> {
            RoomFloor roomFloor = new RoomFloor();
            roomFloor.setApartmentId(concentratedAddVO.getApartmentId());
            roomFloor.setApartmentAreaId(finalRoomApartmentArea.getId());
            roomFloor.setFloorRoomNum(concentratedAddVO.getFloorRoomNum());
            roomFloor.setNum(floor.getKey());
            roomFloor.setName(floor.getKey() + "楼");
            roomFloor.setTenantId(tenantId);
            roomFloorRepository.save(roomFloor);

            List<RoomInfoDto> roomInfoDtos = floor.getValue();
            roomInfoDtos.stream().forEach(roomInfoDto -> {
                RoomHouse roomHouse = new RoomHouse();
                roomHouse.setId(IdUtil.getSnowflakeNextId());
                roomHouse.setName(roomInfoDto.getName());
                roomHouse.setNo(codeUtil.nextCode(apartment.getSourceType().equals(String.valueOf(1)) ? "101" : "201"));
                roomHouse.setProvince(concentratedAddVO.getProvince());
                roomHouse.setCity(concentratedAddVO.getCity());
                roomHouse.setDistrict(concentratedAddVO.getDistrict());
                roomHouse.setStreet(concentratedAddVO.getStreet());
                roomHouse.setAddress(concentratedAddVO.getAddress());
                roomHouse.setArea(concentratedAddVO.getAreaName());
                roomHouse.setTenantId(tenantId);
                RoomLayout roomLayout = roomLayoutRepository.getById(roomInfoDto.getLayoutId());
                roomHouse.setSpace(Double.valueOf(roomLayout.getSpaceMin()));
                roomHouse.setApartmentId(concentratedAddVO.getApartmentId());
                roomHouse.setHouseNo(roomInfoDto.getName());
                roomHouse.setIsWhole(true);
                roomHouse.setRoomNum(0);
                roomHouse.setLayoutId(roomInfoDto.getLayoutId());
                roomHouse.setIsStop(false);
                roomHouse.setFloorId(roomFloor.getId());
                roomHouse.setFloorNo(roomFloor.getNum().toString());
                roomHouse.setDecoration(recordInfoDto.getDecoration());
                roomHouse.setToward(roomInfoDto.getToward());
                roomHouse.setIsConcentrated(true);
                roomHouse.setApartmentAreaId(finalRoomApartmentArea.getId());
                roomHouse.setRoomHouseTypeId(roomLayout.getRoomHouseTypeId());
                roomHouse.setIsLock(false);
                roomHouse.setDeptId(apartment.getDeptId());
                roomHouse.setMonthRental(roomLayout.getMonthRental());
                roomHouse.setBuildingNo(finalRoomApartmentArea.getBuildingNo());
                roomHouse.setUnitNo(finalRoomApartmentArea.getUnitNo());
                roomHouse.setRoomUsage(concentratedAddVO.getRoomUsage());
                roomHouse.setIsClean(true);
                roomHouse.setIsRepair(false);
                //roomHouse.setProportion(Double.valueOf(roomLayout.getSpaceMin()));
                roomHouseRepository.save(roomHouse);

                // 创建房源时，加入一条空的房态
                RoomStateRecord roomStateRecord = new RoomStateRecord();
                roomStateRecord.setRoomId(roomHouse.getId());
                roomStateRecord.setIsCurrentState(true);
                roomStateRecord.setState(RentStatusEnum.EMPTY.getValue());
                roomStateRecordRepository.save(roomStateRecord);

                roomHouseInfo.setRoomHouseId(roomHouse.getId());
                roomHouseInfo.setId(null);
                roomHouseInfoRepository.save(roomHouseInfo);
                // 组装ES所需数据
                StringBuilder sb = new StringBuilder();
                sb.append(roomHouse.getArea());
                sb.append(finalRoomApartmentArea.getBuildingNo());
                sb.append("栋");
                if (!roomHouse.getIsConcentrated()) {
                    sb.append(finalRoomApartmentArea.getUnitNo());
                    sb.append("单元");
                }
                sb.append(roomHouse.getName());
                String fullName = sb.toString();

                RoomelCreateReqVO roomelCreateReqVO = new RoomelCreateReqVO();
                roomelCreateReqVO.setId(roomHouse.getId());
                roomelCreateReqVO.setFullName(fullName);
                roomelCreateReqVO.setSuperId(roomHouse.getSuperId());
                roomelCreateReqVO.setApartmentAreaId(finalRoomApartmentArea.getId());
                roomelCreateReqVO.setApartmentAreaName(finalRoomApartmentArea.getArea());
                roomelCreateReqVO.setApartmentName(apartment.getName());
                roomelCreateReqVO.setApartmentId(apartment.getId());
                roomelCreateReqVO.setIsConcentrated(roomHouse.getIsConcentrated());
                roomelCreateReqVO.setApartmentAreaLat(roomArea.getGeoLat());
                roomelCreateReqVO.setApartmentAreaLon(roomArea.getGeoLng());
                roomelCreateReqVO.setApartmentLat(apartment.getLatitude());
                roomelCreateReqVO.setApartmentLon(apartment.getLongitude());
                roomelCreateReqVO.setSourceType(apartment.getSourceType());
                roomelCreateReqVO.setFloorId(roomHouse.getFloorId());
                roomelCreateReqVO.setBuildingNo(finalRoomApartmentArea.getBuildingNo());
                roomelCreateReqVO.setUnitNo(finalRoomApartmentArea.getUnitNo());
                roomelCreateReqVO.setFloorNo(Integer.valueOf(roomHouse.getFloorNo()));
                roomelCreateReqVO.setFloorSum(finalRoomApartmentArea.getFloorNum());
                roomelCreateReqVO.setCity(finalRoomApartmentArea.getCity());
                roomelCreateReqVO.setDistrict(finalRoomApartmentArea.getDistrict());
                roomelCreateReqVO.setStreet(finalRoomApartmentArea.getStreet());
                roomelCreateReqVO.setAddress(finalRoomApartmentArea.getAddress());
                RoomHouseType roomHouseType = roomHouseTypeRepository.getById(roomLayout.getRoomHouseTypeId());
                roomelCreateReqVO.setBedroomNum(roomHouseType.getBedRoomNum());
                roomelCreateReqVO.setLivingroomNum(roomHouseType.getLivingRoomNum());
                roomelCreateReqVO.setKitchenNum(roomHouseType.getKitchenNum());
                roomelCreateReqVO.setToiletNum(roomHouseType.getToiletNum());
                roomelCreateReqVO.setBalcony(roomHouseType.getBalcony());
                roomelCreateReqVO.setRoomHouseTypeId(roomLayout.getRoomHouseTypeId());
                roomelCreateReqVO.setRoomHouseTypeName(roomHouseType.getName());
                roomelCreateReqVO.setLayoutId(roomLayout.getId());
                roomelCreateReqVO.setLayoutName(roomLayout.getName());
                roomelCreateReqVO.setFacetoType(roomHouse.getToward());
                roomelCreateReqVO.setIsWhole(roomHouse.getIsWhole());
                roomelCreateReqVO.setSpace(roomHouse.getSpace());
                roomelCreateReqVO.setDecoration(roomHouse.getDecoration());
                roomelCreateReqVO.setHouseState(RentStatusEnum.EMPTY.getValue());
                roomelCreateReqVO.setRoomHouseName(roomHouse.getName());
                roomelCreateReqVO.setIsScheduled(false);
                roomelCreateReqVO.setTenantId(tenantId);
                roomelCreateReqVO.setRoomHouseNo(roomHouse.getNo());
                roomelCreateReqVO.setHouseNo(roomHouse.getHouseNo());
                roomelCreateReqVO.setIsLock(false);
                roomelCreateReqVO.setIsStop(false);
                roomelCreateReqVO.setPublicFacilities(roomHouse.getPublicFacilities());
                roomelCreateReqVO.setPrice(roomHouse.getMonthRental());
                roomelCreateReqVO.setCreateTime(LocalDateTime.now());
                roomelCreateReqVO.setDeptId(roomHouse.getDeptId());
                roomelCreateReqVO.setRoomAreaId(finalRoomApartmentArea.getRoomAreaId());
                roomelCreateReqVO.setToward(roomHouse.getToward());
                roomelCreateReqVO.setRoomUsage(roomHouse.getRoomUsage());
                roomelCreateReqVO.setIsClean(true);
                roomelCreateReqVO.setIsRepair(false);
                //roomelCreateReqVO.setProportion(roomHouse.getProportion());
                roomelCreateReqVOS.add(roomelCreateReqVO);
            });
        });
        // 推送房源信息到es
        roomEsProducer.ListAddRoomEl(roomelCreateReqVOS);
    }

    /**
     * 保存公寓小区信息
     *
     * @param concentratedAddVO
     * @param tenantId
     * @return
     */
    @NotNull
    private RoomApartmentArea saveApartmentArea(ConcentratedAddVO concentratedAddVO, RoomArea roomArea, Long tenantId) {
        RoomApartmentArea roomApartmentArea = new RoomApartmentArea();
        roomApartmentArea.setApartmentId(concentratedAddVO.getApartmentId());
        roomApartmentArea.setRoomAreaId(roomArea.getId());
        roomApartmentArea.setIsConcentrated(true);
        roomApartmentArea.setBuildingNo(concentratedAddVO.getBuildingNo());
        roomApartmentArea.setUnitNo(concentratedAddVO.getUnitNo());
        roomApartmentArea.setArea(concentratedAddVO.getAreaName());
        roomApartmentArea.setProvince(concentratedAddVO.getProvince());
        roomApartmentArea.setCity(concentratedAddVO.getCity());
        roomApartmentArea.setDistrict(concentratedAddVO.getDistrict());
        roomApartmentArea.setStreet(concentratedAddVO.getStreet());
        roomApartmentArea.setAddress(concentratedAddVO.getAddress());
        roomApartmentArea.setFloorNum(concentratedAddVO.getFloorNum());
        roomApartmentArea.setGroundFloorNum(concentratedAddVO.getGroundFloorNum());
        roomApartmentArea.setFloorRoomNum(concentratedAddVO.getFloorRoomNum());
        roomApartmentArea.setRoomNum(concentratedAddVO.getGroundFloorNum() * concentratedAddVO.getFloorRoomNum());
        roomApartmentArea.setLatitude(roomArea.getGeoLat());
        roomApartmentArea.setLongitude(roomArea.getGeoLng());
        roomApartmentArea.setTenantId(tenantId);
        roomApartmentAreaRepository.save(roomApartmentArea);
        return roomApartmentArea;
    }


    /**
     * 如果小区不存在,创建小区
     *
     * @param areaId   小区id
     * @param areaName 小区名
     * @param province 省
     * @param city     市
     * @param district 区
     * @param street   街道
     * @param address  地址
     * @return
     */
    private RoomArea addRoomArea(Long areaId, String areaName, String province, String city, String district, String street, String address) {
        RoomArea roomArea = roomAreaRepository.get(city, district, street, areaName, address);
        if (ObjectUtil.isEmpty(roomArea)) {
            roomArea = new RoomArea();
            roomArea.setName(areaName);
            Pinyin4jEngine engine = new Pinyin4jEngine();
            roomArea.setEname(engine.getPinyin(areaName, ""));
            roomArea.setCity(city);
            roomArea.setDistrict(district);
            roomArea.setAddress(address);
            roomArea.setStreet(street);
            // 获取经纬度
            String location = " , ";
            province = ObjectUtil.isNotEmpty(roomArea.getProvince()) ? roomArea.getProvince() : "";
            city = ObjectUtil.isNotEmpty(roomArea.getCity()) ? roomArea.getCity() : "";
            district = ObjectUtil.isNotEmpty(roomArea.getDistrict()) ? roomArea.getDistrict() : "";
            street = ObjectUtil.isNotEmpty(roomArea.getStreet()) ? roomArea.getStreet() : "";
            areaName = ObjectUtil.isNotEmpty(roomArea.getName()) ? roomArea.getName() : "";
            address = ObjectUtil.isNotEmpty(roomArea.getAddress()) ? roomArea.getAddress() : "";
            String realAddress = province + city + district + street + areaName + address;
            try {
                location = baiDuMapUtil.locationSearch(realAddress,city);
            } catch (Exception e) {
                log.info(e.getMessage());
                throw new ServiceException(ADDRESS_ERROR);
            }
            if(ObjectUtil.isEmpty(location)){
                throw new ServiceException(ADDRESS_ERROR);
            }
            String[] split = location.split(",");
            roomArea.setGeoLng(split[0]);
            roomArea.setGeoLat(split[1]);
            roomAreaRepository.save(roomArea);
        }
        return roomArea;
    }

    /**
     * 根据id列表查询对应房间基本信息和户型信息
     *
     * @param ids
     * @return
     */
    @Override
    public CommonResult<List<RoomHouseRespVo>> getRoomHouseAndLayoutByIds(List<Long> ids) {
        List<RoomHouse> roomHouses = roomHouseRepository.listByIds(ids);
        List<RoomHouseRespVo> respVoList = RoomHouseConvert.INSTANCE.convert(roomHouses);
        if(CollectionUtil.isNotEmpty(respVoList)){
            //分组获取户型id集合
            Map<Long, List<RoomHouseRespVo>> collect = respVoList.stream().collect(Collectors.groupingBy(RoomHouseRespVo::getRoomHouseTypeId));
            List<RoomHouseType> roomHouseTypes = roomHouseTypeRepository.listByIds(collect.keySet());
            if(CollectionUtil.isNotEmpty(roomHouseTypes)){
                respVoList.forEach(f->{
                    roomHouseTypes.stream().filter(rh->rh.getId().compareTo(f.getRoomHouseTypeId())==0).findFirst().ifPresent(p->{
                        f.setRoomHouseTypeName(p.getName());
                    });
                });
            }
        }

        return CommonResult.success(respVoList);

    }
}
